{"id":6669,"date":"2018-05-30T08:58:36","date_gmt":"2018-05-30T06:58:36","guid":{"rendered":"https:\/\/anexia.com\/stagingblog\/?p=6669"},"modified":"2022-07-22T13:12:08","modified_gmt":"2022-07-22T11:12:08","slug":"restful-api-with-laravel","status":"publish","type":"post","link":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/","title":{"rendered":"RESTful API with Laravel"},"content":{"rendered":"<h2>What ist Lavarel?<\/h2>\n<p>Just a few years ago web applications were still built in such a way that interactions with the database and view were executed directly by the application itself. Yet with the increasing popularity of mobile apps and JavaScript frameworks, central30<\/p>\n<p>Laravel is an open-source framework written in PHP that was initiated by Taylor Otwell in 2011. It has subsequently enjoyed great popularity thanks to its simplicity and flexibility, and it also scores with its community spread around the world.<\/p>\n<h2>REST &#8211; what this contains<\/h2>\n<p>The term \u2018RESTful API\u2019 is surely a known expression for many of you. To examine this more closely, however, we first need to understand what \u2018REST\u2019 actually stands for and what principles it follows.<\/p>\n<p>REST is short for \u2018<strong>RE<\/strong>presentational <strong>S<\/strong>tate <strong>T<\/strong>ransfer\u2019, and it designates a programming paradigm for communication between the applications via a stateless protocol (usually HTTP). This is particularly relevant for distributed systems, particularly for web services.<\/p>\n<h3>HTTP methods define actions<\/h3>\n<p>In REST-compatible APIs the resources represent the endpoints and HTTP methods represent the associated actions. Which action should be initiated with which mode of access is defined precisely:<\/p>\n<ul>\n<li><strong>GET: Read resource<\/strong><br \/>\nLoads information of the desired resource from the server, causing no side effects. According to the specification, GET requests must be \u2018secure\u2019, i.e. a request may not have any effects on the resource. This behavior is termed nullipotent.<\/li>\n<li><strong>POST: Create new resource<\/strong><br \/>\nCreates a new resource in the appropriate resource master using the data transmitted. With each invocation it creates new resources rather than returning the equivalents again. This behavior is termed not idempotent.<\/li>\n<li><strong>PUT: Update existing resource<\/strong><br \/>\nUpdates an existing resource using the data transmitted. Subsequent invocations do not cause further side effects. In contrast to POST, this behavior is here designated as idempotent.<\/li>\n<li><strong>DELETE: Delete resource<\/strong><br \/>\nDeletes the requested resource, and similarly to PUT, its behavior is also idempotent.<\/li>\n<\/ul>\n<p>The HTTP methods <strong>HEAD<\/strong>, <strong>OPTIONS<\/strong>, <strong>CONNECT<\/strong> and <strong>TRACE<\/strong> are optional, and are normally not required for CRUD operations. It is also important to point out here that adding an implementation of CONNECT or TRACE could affect the security of the application.<\/p>\n<h3>Storing data: POST vs. PUT<\/h3>\n<p>When it comes to data storage, be it a new create or an update, opinions are divided as to whether one should use POST, PUT or indeed PATCH (partial update).<\/p>\n<p>The following examples are based on making updates to resources using PUT. PUT means creating or updating a resource at a defined location.<\/p>\n<p>What also defines PUT is its idempotence. In other words, repeated requests using the same data will in fact only result in a single change.<\/p>\n<h2>Integration of REST in Laravel<\/h2>\n<p>Originally this framework was solely intended to be an improved alternative to the already popular <a href=\"https:\/\/www.codeigniter.com\" target=\"_blank\" rel=\"noopener\">CodeIgniter<\/a> framework, since this lacked certain features such as authentication-related functions.<\/p>\n<p>Over time, however, its scope of functions increased substantially, bringing with it both support for dependency injections and its own template engine (\u2018Blade\u2019).<\/p>\n<p>A further breakthrough occurred in 2012 with the \u2018Artisan\u2019 command-line tool, which enabled all interactions to be executed directly with the framework via the console. This was also followed by support for a still wider range of database systems.<\/p>\n<p>With Version 4 the Laravel framework could then be loaded and managed wholly via Composer, which increased its expandability accordingly and so gave developers still more freedoms.<\/p>\n<p>Further information on this is available directly on the Laravel framework <a href=\"https:\/\/laravel.com\" target=\"_blank\" rel=\"noopener\">homepage<\/a>.<\/p>\n<p>For the following examples we assume that the Laravel framework has already been installed and is executable. It is of no relevance whether this is done via <a href=\"https:\/\/laravel.com\/docs\/5.6\/homestead\" target=\"_blank\" rel=\"noopener\">Homestead<\/a>, Composer or indeed by means of a manual installation of a published release from GitHub. The database connection should also already be configured and functioning.<\/p>\n<h2>Creating a resource<\/h2>\n<p>For the following example we assume that the model name is identical to the resource name. This is not strictly necessary but it is very helpful for promoting traceability.<\/p>\n<p>As the resource, we will create a \u2018note\u2019 that features a \u2018Subject\u2019 and a \u2018Body\u2019 of text.<\/p>\n<p>Let us start by creating the model, including migration using the \u2018<a href=\"https:\/\/laravel.com\/docs\/5.6\/artisan\" target=\"_blank\" rel=\"noopener\">Artisan<\/a>\u2019 command-line tool supplied with Laravel.<\/p>\n<p>To do this we navigate, using the terminal (Linux) or the prompt (Windows) directly to the project folder and enter the following command:<\/p>\n<p><strong>php artisan make:model Note -m<\/strong><\/p>\n<p>This command generates a new model called \u2018Note\u2019, and the optional parameter \u2018m\u2019 specifies that an appropriate migration is to be created along with it. The model just created is located at <strong>.\/app\/Note.php<\/strong> and the related migration is at <strong>.\/database\/migrations\/YYYY_MM_DD_XXXXXX_create_notes_table.php<\/strong>.<\/p>\n<p>Let us first look at the migration.<\/p>\n<pre class=\"lang:php decode:true\">&lt;?php\r\n\r\nuse Illuminate\\Support\\Facades\\Schema;\r\nuse Illuminate\\Database\\Schema\\Blueprint;\r\nuse Illuminate\\Database\\Migrations\\Migration;\r\n\r\nclass CreateNotesTable extends Migration\r\n{\r\n    \/**\r\n     * Run the migrations.\r\n     *\r\n     * @return void\r\n     *\/\r\n    public function up()\r\n    {\r\n        Schema::create('notes', function (Blueprint $table) {\r\n            $table-&gt;increments('id');\r\n            $table-&gt;timestamps();\r\n        });\r\n    }\r\n\r\n    \/**\r\n     * Reverse the migrations.\r\n     *\r\n     * @return void\r\n     *\/\r\n    public function down()\r\n    {\r\n        Schema::dropIfExists('notes');\r\n    }\r\n}\r\n<\/pre>\n<p>The <strong>up()<\/strong> and <strong>down()<\/strong> methods are used to execute the migration and to reverse it, respectively.<\/p>\n<p>The line <strong>$table-&gt;increments(&#8218;id&#8216;)<\/strong> specifies that an INT field is created for this, with Auto Increment as the primary key. The instruction <strong>$table-&gt;timestamps()<\/strong> ensures that the \u2018created_at\u2019 and \u2018updated_at\u2019 fields, which are managed by Laravel, are also created. Whether these should in fact be used or not can also be configured directly within the model, but the above is used as standard.<\/p>\n<p>Let us now add our two fields, \u2018Subject\u2019 and \u2018Body\u2019, to the migration just created, so that the <strong>up()<\/strong> method finally looks as follows:<\/p>\n<pre class=\"lang:php decode:true \">public function up()\r\n{\r\n\tSchema::create('notes', function (Blueprint $table) {\r\n\t\t$table-&gt;increments('id');\r\n\t\t$table-&gt;string('subject');\r\n\t\t$table-&gt;text('body');\r\n\t\t$table-&gt;timestamps();\r\n\t});\r\n}<\/pre>\n<p>We can now run the migration using the following command:<\/p>\n<p><strong>php artisan migrate<\/strong><\/p>\n<p>Should you run into an error such as \u2018<strong><em>Specified key was too long error<\/em><\/strong><em>\u2019<\/em>, the following step may help.<\/p>\n<p>For this, we extend the app service provider at <strong>.\/app\/Providers\/AppServiceProvider.php<\/strong> as follows and then repeat the previous step:<\/p>\n<pre class=\"lang:php decode:true \">use Illuminate\\Support\\Facades\\Schema;\r\n\r\npublic function boot()\r\n{\r\n\tSchema::defaultStringLength(191);\r\n}<\/pre>\n<p>Let us now return to our model, \u2018Note\u2019. We will add the \u2018protected\u2019-attribute &#8218;fillable&#8216; to this and specify which of its fields can be populated in the database.<\/p>\n<pre class=\"lang:php decode:true \">&lt;?php\r\n\r\nnamespace App;\r\n\r\nuse Illuminate\\Database\\Eloquent\\Model;\r\n\r\nclass Note extends Model\r\n{\r\n\r\n\t\/**\r\n\t * @var array\r\n\t *\/\r\n\tprotected $fillable = ['subject', 'body'];\r\n}<\/pre>\n<h2>Database seeding<\/h2>\n<p>Database seeding is understood as the filling (populating) of a database or database table (in relational systems) with test data. These data are normally generated dynamically using the random principle.<\/p>\n<p>Let us now use the following command to create a seeder class that will fill our Notes table with test data:<\/p>\n<p><strong>php artisan make:seeder NotesSeeder<\/strong><\/p>\n<p>Next we open the seeder class just created at <strong>.\/database\/seeds\/NotesSeeder.php<\/strong> and enter the following:<\/p>\n<pre class=\"lang:php decode:true \">&lt;?php\r\n\r\nuse Illuminate\\Database\\Seeder;\r\nuse App\\Note;\r\n\r\nclass NotesSeeder extends Seeder\r\n{\r\n\t\/**\r\n\t * Run the database seeds.\r\n\t *\r\n\t * @return void\r\n\t *\/\r\n\tpublic function run()\r\n\t{\r\n\t\t\/\/ truncate already existing data\r\n\t\tNote::truncate();\r\n\r\n\t\t\/\/ make instance of the Faker-class\r\n\t\t$faker = \\Faker\\Factory::create();\r\n\r\n\t\t\/\/ insert some random generated records\r\n\t\tfor ($i = 0; $i &lt; 200; $i++) {\r\n\t\t\tNote::create([\r\n\t\t\t\t'subject' =&gt; $faker-&gt;sentence(),\r\n\t\t\t\t'body' =&gt; $faker-&gt;paragraph(),\r\n\t\t\t]);\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>The faker class enables random pseudo-content to be generated, selectable by type. First, the database table is cleared, so that with each execution of the seeder we can start afresh. A loop is now used to generate and store 200 random entries. Next, to run the seeder, let us make use of Artisan again:<\/p>\n<p><strong>php artisan db:seed &#8211;class=NotesSeeder<\/strong><\/p>\n<p>Should we have multiple seeder classes, it would be simpler to add these to the central \u2018database seeder\u2019 by registering the individual seeder classes we have created in the <strong>run()<\/strong> method of the <strong>DatabaseSeeder()<\/strong> class in the same directory.<\/p>\n<pre class=\"lang:php decode:true \">&lt;?php\r\n\r\nuse Illuminate\\Database\\Seeder;\r\n\r\nclass DatabaseSeeder extends Seeder\r\n{\r\n\t\/**\r\n\t * Run the database seeds.\r\n\t *\r\n\t * @return void\r\n\t *\/\r\n\tpublic function run()\r\n\t{\r\n\t\t$this-&gt;call( NotesSeeder::class );\r\n\t}\r\n}<\/pre>\n<p>Now we can use the Artisan seed command to execute all the seeders registered in the <strong>DatabaseSeeder()<\/strong> without specifying a particular class.<\/p>\n<p><strong>php artisan db:seed<\/strong><\/p>\n<h2>Creating a resource controller<\/h2>\n<p>In order for us to interact with the data, we require a controller to manage the communication between the client and the database. In this case, however, we require what is known as a resource controller &#8211; that is, one that implements at least the following actions: <strong>index()<\/strong>, <strong>store()<\/strong>, <strong>update()<\/strong> and <strong>destroy()<\/strong>. To do this, we use Artisan again:<\/p>\n<p><strong>php artisan make:controller NotesController<\/strong><\/p>\n<p>The newly created <strong>NotesController()<\/strong> is located at <strong>.\/app\/Http\/Controllers\/NotesController.php<\/strong>. Let us now create the actions listed above and implement the basic behavior.<\/p>\n<pre class=\"lang:php decode:true \">&lt;?php\r\n\r\nnamespace App\\Http\\Controllers;\r\n\r\nuse Illuminate\\Http\\Request;\r\nuse App\\Note;\r\n\r\nclass NotesController extends Controller\r\n{\r\n\t\/**\r\n\t * Index function for general listing.\r\n\t *\r\n\t * @param Request $request\r\n\t *\r\n\t * @return \\Illuminate\\Http\\JsonResponse\r\n\t *\/\r\n\tpublic function index(Request $request)\r\n\t{\r\n\t\t$notes = Note::all();\r\n\r\n\t\treturn response()-&gt;json($notes);\r\n\t}\r\n\r\n\r\n\t\/**\r\n\t * Store-Action\r\n\t *\r\n\t * @param Request $request\r\n\t *\r\n\t * @return \\Illuminate\\Http\\JsonResponse\r\n\t *\/\r\n\tpublic function store(Request $request)\r\n\t{\r\n\t\t$note = Note::create($request-&gt;all());\r\n\r\n\t\treturn response()-&gt;json($note);\r\n\t}\r\n\r\n\r\n\t\/**\r\n\t * Show-Action\r\n\t *\r\n\t * @param Request $request\r\n\t * @param int $id\r\n\t *\r\n\t * @return \\Illuminate\\Http\\JsonResponse\r\n\t *\/\r\n\tpublic function show(Request $request, $id)\r\n\t{\r\n\t\t$note = Note::find($id);\r\n\r\n\t\treturn response()-&gt;json($note);\r\n\t}\r\n\r\n\r\n\t\/**\r\n\t * Update-Action\r\n\t *\r\n\t * @param Request $request\r\n\t * @param int $id\r\n\t *\r\n\t * @return \\Illuminate\\Http\\JsonResponse\r\n\t *\/\r\n\tpublic function update(Request $request, $id)\r\n\t{\r\n\t\t$note = Note::findOrFail($id);\r\n\t\t$note-&gt;update($request-&gt;all());\r\n\r\n\t\treturn response()-&gt;json($note);\r\n\r\n\r\n\t}\r\n\r\n\r\n\t\/**\r\n\t * Destroy-Action\r\n\t *\r\n\t * @param Request $request\r\n\t * @param int $id\r\n\t *\r\n\t * @return \\Illuminate\\Http\\JsonResponse\r\n\t *\/\r\n\tpublic function destroy(Request $request, $id)\r\n\t{\r\n\t\tNote::find($id)-&gt;delete();\r\n\r\n\t\treturn response()-&gt;json([], 204);\r\n\t}\r\n}<\/pre>\n<p>If there are more than one resource controller, it would make sense to create a base resource controller and allow the various resource controllers to inherit from this. This gives the advantage of being able to use the base behavior in each controller while also allowing specific actions to be overwritten for individual controllers.<\/p>\n<h2>Registering API routes<\/h2>\n<p>Now that the basic CRUD behavior is implemented, the routes must be defined. To do this we open the file <strong>.\/routes\/api.php<\/strong> and add the following lines to it:<\/p>\n<pre class=\"lang:php decode:true \">Route::resource('notes', 'NotesController');<\/pre>\n<p>The route configuration of Laravel makes it possible by this means to route an endpoint directly to a <a href=\"https:\/\/laravel.com\/docs\/5.6\/controllers#resource-controllers\" target=\"_blank\" rel=\"noopener\">resource controller<\/a>.For this purpose Laravel has reserved specific actions for itself with each controller. These are those that we created previously with <strong>NotesController()<\/strong>. The following table gives an indication of the URL structure for such a resource controller and of which action is present behind which HTTP method.<\/p>\n<table style=\"width: 443px;\">\n<tbody>\n<tr>\n<td style=\"width: 170px;\"><strong>HTTP connection type<\/strong><\/td>\n<td style=\"width: 96px;\"><strong>URI<\/strong><\/td>\n<td style=\"width: 54px;\"><strong>Action<\/strong><\/td>\n<td style=\"width: 97px;\"><strong>Route name<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 170px;\"><strong>GET<\/strong><\/td>\n<td style=\"width: 96px;\">\/notes<\/td>\n<td style=\"width: 54px;\">index<\/td>\n<td style=\"width: 97px;\">notes.index<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 170px;\"><strong>GET<\/strong><\/td>\n<td style=\"width: 96px;\">\/notes\/create<\/td>\n<td style=\"width: 54px;\">create<\/td>\n<td style=\"width: 97px;\">notes.create<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 170px;\"><strong>POST<\/strong><\/td>\n<td style=\"width: 96px;\">\/notes<\/td>\n<td style=\"width: 54px;\">store<\/td>\n<td style=\"width: 97px;\">notes.store<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 170px;\"><strong>GET<\/strong><\/td>\n<td style=\"width: 96px;\">\/notes\/{id}<\/td>\n<td style=\"width: 54px;\">show<\/td>\n<td style=\"width: 97px;\">notes.show<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 170px;\"><strong>GET<\/strong><\/td>\n<td style=\"width: 96px;\">\/notes\/{id}\/edit<\/td>\n<td style=\"width: 54px;\">edit<\/td>\n<td style=\"width: 97px;\">notes.edit<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 170px;\"><strong>PUT\/PATCH<\/strong><\/td>\n<td style=\"width: 96px;\">\/notes\/{id}<\/td>\n<td style=\"width: 54px;\">update<\/td>\n<td style=\"width: 97px;\">notes.update<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 170px;\"><strong>DELETE<\/strong><\/td>\n<td style=\"width: 96px;\">\/notes\/{id}<\/td>\n<td style=\"width: 54px;\">destroy<\/td>\n<td style=\"width: 97px;\">notes.destroy<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>It should be noted here that the actions <strong>create()<\/strong> and <strong>edit()<\/strong> have not been implemented in our resource controller. The reason for this is, that with both these actions, only the specific (HTML) form should be delivered via GET. Once our resource endpoint delivers only JSON data, however, this would then be void.<\/p>\n<h2>HTTP status codes<\/h2>\n<p>With REST APIs, in addition to the HTTP methods, other factors including the HTTP status codes and their meanings are also defined. The following listing gives a brief overview.<\/p>\n<ul>\n<li><strong>200:<\/strong> OK, no errors occurred<\/li>\n<li><strong>201:<\/strong> Object has been created<\/li>\n<li><strong>204:<\/strong> No contents &#8211; indicates that an action was successful but did not return any content<\/li>\n<li><strong>206:<\/strong> Partial contents &#8211; used e.g. with paginated content<\/li>\n<li><strong>400:<\/strong> Invalid request &#8211; standard response code if request was not valid<\/li>\n<li><strong>401:<\/strong> Unauthorized &#8211; either the user is not authorized or a log-in is required<\/li>\n<li><strong>403:<\/strong> Denied &#8211; the user is logged in but is not authorized to perform this action<\/li>\n<li><strong>404:<\/strong> Not found &#8211; the desired resource or endpoint does not exist<\/li>\n<li><strong>500:<\/strong> Internal server error &#8211; should not normally occur, but indicates that an unexpected error has occurred at the server while processing the request<\/li>\n<li><strong>503:<\/strong> Service not available &#8211; indicates that the requested resource or endpoint is temporarily unavailable<\/li>\n<\/ul>\n<p>The use of these status codes is not mandatory, but if development is to be REST-compliant, they are indispensable.<\/p>\n<h2>Summary<\/h2>\n<p>In a time in which rich internet applications (RIA) and single-page applications such as Angular or even React are enjoying immense popularity and in which apps for mobile devices must also access central master data ever more frequently, it is increasingly important that consistent communications channels are used.<\/p>\n<p>The use of REST-compliant (RESTful) APIs makes this relatively straightforward to realize in practice.<\/p>\n<p>What was not discussed in these examples, however, for the sake of simplicity, is securing the APIs. This point is particularly relevant where data can be modified. There is a very wide spectrum of possible variants &#8211; from simple tokens (such as JSON web tokens, JWTs) through to complex OAuth authentication.<\/p>\n<h2>Further Information<\/h2>\n<p><a href=\"https:\/\/anexia.com\/en\/software-development\/app-development\" target=\"_blank\" rel=\"noopener\">Custom App Development<\/a><br \/>\n<a href=\"https:\/\/anexia.com\/en\/software-development\/web-development\" target=\"_blank\" rel=\"noopener\">Web development by Anexia<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Manuel presents the RESTful API with Laravel:  RESTful APIs are elegant solutions for providing an interface between the client and the data source.<\/p>\n","protected":false},"author":15,"featured_media":2961,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1135,2211],"tags":[1610,1343,1612,1329,1614,1616,1327],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>RESTful API with Laravel - ANEXIA Blog<\/title>\n<meta name=\"description\" content=\"Manuel presents the RESTful API with Laravel: RESTful APIs are elegant solutions for providing an interface between the client and the data source.{:}\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"RESTful API with Laravel - ANEXIA Blog\" \/>\n<meta property=\"og:description\" content=\"Manuel presents the RESTful API with Laravel: RESTful APIs are elegant solutions for providing an interface between the client and the data source.{:}\" \/>\n<meta property=\"og:url\" content=\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/\" \/>\n<meta property=\"og:site_name\" content=\"ANEXIA Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/anexiagmbh\/\" \/>\n<meta property=\"article:published_time\" content=\"2018-05-30T06:58:36+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-07-22T11:12:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/anexia.com\/blog\/wp-content\/uploads\/2017\/09\/ManuelWutte-Blog-Teaser.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"672\" \/>\n\t<meta property=\"og:image:height\" content=\"372\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manuel Wutte\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@_ANEXIA\" \/>\n<meta name=\"twitter:site\" content=\"@_ANEXIA\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manuel Wutte\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"12\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/\",\"url\":\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/\",\"name\":\"RESTful API with Laravel - ANEXIA Blog\",\"isPartOf\":{\"@id\":\"https:\/\/anexia.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/anexia.com\/blog\/wp-content\/uploads\/2017\/09\/ManuelWutte-Blog-Teaser.jpg\",\"datePublished\":\"2018-05-30T06:58:36+00:00\",\"dateModified\":\"2022-07-22T11:12:08+00:00\",\"author\":{\"@id\":\"https:\/\/anexia.com\/blog\/#\/schema\/person\/926f6b9e5aeed88b145cf86d87fd09de\"},\"description\":\"Manuel presents the RESTful API with Laravel: RESTful APIs are elegant solutions for providing an interface between the client and the data source.{:}\",\"breadcrumb\":{\"@id\":\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#primaryimage\",\"url\":\"https:\/\/anexia.com\/blog\/wp-content\/uploads\/2017\/09\/ManuelWutte-Blog-Teaser.jpg\",\"contentUrl\":\"https:\/\/anexia.com\/blog\/wp-content\/uploads\/2017\/09\/ManuelWutte-Blog-Teaser.jpg\",\"width\":672,\"height\":372},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/anexia.com\/blog\/de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"RESTful API with Laravel\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/anexia.com\/blog\/#website\",\"url\":\"https:\/\/anexia.com\/blog\/\",\"name\":\"ANEXIA Blog\",\"description\":\"[:de] ANEXIA Blog - Technischen Themen, Anexia News und Insights [:]\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/anexia.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"de\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/anexia.com\/blog\/#\/schema\/person\/926f6b9e5aeed88b145cf86d87fd09de\",\"name\":\"Manuel Wutte\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/anexia.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/9528a61f48f4294cd5f7cd8a4141bd55?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/9528a61f48f4294cd5f7cd8a4141bd55?s=96&d=mm&r=g\",\"caption\":\"Manuel Wutte\"},\"url\":\"https:\/\/anexia.com\/blog\/author\/mwu\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"RESTful API with Laravel - ANEXIA Blog","description":"Manuel presents the RESTful API with Laravel: RESTful APIs are elegant solutions for providing an interface between the client and the data source.{:}","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/","og_locale":"de_DE","og_type":"article","og_title":"RESTful API with Laravel - ANEXIA Blog","og_description":"Manuel presents the RESTful API with Laravel: RESTful APIs are elegant solutions for providing an interface between the client and the data source.{:}","og_url":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/","og_site_name":"ANEXIA Blog","article_publisher":"https:\/\/www.facebook.com\/anexiagmbh\/","article_published_time":"2018-05-30T06:58:36+00:00","article_modified_time":"2022-07-22T11:12:08+00:00","og_image":[{"width":672,"height":372,"url":"https:\/\/anexia.com\/blog\/wp-content\/uploads\/2017\/09\/ManuelWutte-Blog-Teaser.jpg","type":"image\/jpeg"}],"author":"Manuel Wutte","twitter_card":"summary_large_image","twitter_creator":"@_ANEXIA","twitter_site":"@_ANEXIA","twitter_misc":{"Verfasst von":"Manuel Wutte","Gesch\u00e4tzte Lesezeit":"12\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/","url":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/","name":"RESTful API with Laravel - ANEXIA Blog","isPartOf":{"@id":"https:\/\/anexia.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#primaryimage"},"image":{"@id":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#primaryimage"},"thumbnailUrl":"https:\/\/anexia.com\/blog\/wp-content\/uploads\/2017\/09\/ManuelWutte-Blog-Teaser.jpg","datePublished":"2018-05-30T06:58:36+00:00","dateModified":"2022-07-22T11:12:08+00:00","author":{"@id":"https:\/\/anexia.com\/blog\/#\/schema\/person\/926f6b9e5aeed88b145cf86d87fd09de"},"description":"Manuel presents the RESTful API with Laravel: RESTful APIs are elegant solutions for providing an interface between the client and the data source.{:}","breadcrumb":{"@id":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#primaryimage","url":"https:\/\/anexia.com\/blog\/wp-content\/uploads\/2017\/09\/ManuelWutte-Blog-Teaser.jpg","contentUrl":"https:\/\/anexia.com\/blog\/wp-content\/uploads\/2017\/09\/ManuelWutte-Blog-Teaser.jpg","width":672,"height":372},{"@type":"BreadcrumbList","@id":"https:\/\/anexia.com\/blog\/en\/restful-api-with-laravel\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/anexia.com\/blog\/de\/"},{"@type":"ListItem","position":2,"name":"RESTful API with Laravel"}]},{"@type":"WebSite","@id":"https:\/\/anexia.com\/blog\/#website","url":"https:\/\/anexia.com\/blog\/","name":"ANEXIA Blog","description":"[:de] ANEXIA Blog - Technischen Themen, Anexia News und Insights [:]","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/anexia.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"de"},{"@type":"Person","@id":"https:\/\/anexia.com\/blog\/#\/schema\/person\/926f6b9e5aeed88b145cf86d87fd09de","name":"Manuel Wutte","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/anexia.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/9528a61f48f4294cd5f7cd8a4141bd55?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9528a61f48f4294cd5f7cd8a4141bd55?s=96&d=mm&r=g","caption":"Manuel Wutte"},"url":"https:\/\/anexia.com\/blog\/author\/mwu\/"}]}},"lang":"en","translations":{"en":6669,"de":3464},"amp_enabled":true,"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/posts\/6669"}],"collection":[{"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/comments?post=6669"}],"version-history":[{"count":3,"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/posts\/6669\/revisions"}],"predecessor-version":[{"id":7532,"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/posts\/6669\/revisions\/7532"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/media\/2961"}],"wp:attachment":[{"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/media?parent=6669"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/categories?post=6669"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/anexia.com\/blog\/wp-json\/wp\/v2\/tags?post=6669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}