Restful APIs in Laravel using Laravel Resource Controllers

This document aims to provide step by step approach to implement RESTful APIs in laravel. Brief description of difference between GET and POST HTTP methods, REST methods is given. However understanding of REST architecture will be an added advantage.

 

Laravel provides methods by which one can implement RESTful APIs easily. With this CRUD (Create, Retrieve, Update, Delete) operations on database can be performed.

 

Let’s have a look at the difference between HTTP methods – GET and POST

The GET Method

  • GET is used to request data from a specified resource.
  • query string (name/value pairs) is sent in the URL of a GET request.

 

The POST Method

  • POST is used to send data to a server to create/update a resource.
  • The data sent to the server with POST is stored in the request body of the HTTP request.

The following table compares the two HTTP methods: GET and POST.

[ninja_tables id=”215366″]

Restful APIs

Architecture for developing web services

In RESTful APIs, we use the HTTP verbs as actions, and the endpoints are the resources (e.g., database) acted upon.

HTTP verbs are:

  • GET: retrieve resources
  • POST: create resources
  • PUT: update resources
  • DELETE: delete resources

Restful APIs in Laravel using resource controllers

  • Laravel resource routing assigns the typical “CRUD” routes to a controller with a single line of code.
  • For example, you may wish to create a controller that handles all HTTP requests for “photos” stored by your application. Using the make:controller Artisan command, we can quickly create such a controller

php artisan make:controller PhotoController –resource

  • This command will generate a controller at app/Http/Controllers/PhotoController.php.
  • The controller will contain a method for each of the available resource operations.
  • Next, you may register a resourceful route to the controller: To be specified in web.php
  • It gives you these named routes as shown in the below table:

 

Route::resource(‘photos’, ‘PhotoController’);

Actions Handled By Resource Controller

[ninja_tables id=”215372″]

Spoofing for PUT, PATCH and DELETE methods

  • Since HTML forms can’t make PUT, PATCH, or DELETE requests, you will need to add a hidden_method field to spoof these HTTP verbs.
  • The @method Blade directive can create this field for you:

<form action=”/foo/bar” method=”POST”>
@method(‘PUT’)
</form>

except,only, match resource routes

  • In case if you wish to customize certain default actions i.e., if you want the controller to handle these actions instead of the default actions use the ‘except’ or ‘only’ partial routes. To be specified in web.php

Route::resource(‘photos’, ‘PhotoController’)->only([
‘index’, ‘show’
]);

Route::resource(‘photos’, ‘PhotoController’)->except([
‘create’, ‘store’, ‘update’, ‘destroy’
]);

  • Sometimes you may need to register a route that responds to multiple HTTP verbs. You may do so using the match method. Or, you may even register a route that responds to all HTTP verbs using the any method:

Route::match([‘get’, ‘post’], ‘/’, function () {
//
});

Methods in Controller

class UsersController extends BaseController

{

public function index() {}

public function show($id) {}

public function store() {}

}

Route precedence

  • If you need to add additional routes to a resource controller beyond the default set of resource routes, you should define those routes before your call to Route::resource; otherwise, the routes defined by the resource method may unintentionally take precedence over your supplemental routes.
  • You should always declare hard-coded routes first, because any wild-card routes would be executed if they’re declared before hard-coded routes.

Route::get(‘/users/{name}’, ‘SomeController@action’);

Route::get(‘/users/admins’, ‘SomeController@action’);

  • In the above the second route will never be called as /users/admins matches the pattern /users/{name} and the first route will get executed instead.
  • In Laravel for routing the statement present at first in Routes.php will be processed first before the others which are below that particular statement. So if you have two same URL the first one will always be used.

 

Protection against CSRF attacks

  • Laravel makes it easy to protect your site against CSRF attacks without any work on your part. However, if you want to submit a form successfully you must include a CSRF token input to verify that the form submission came from the application and not from another site.
  • Laravel automatically generates a CSRF “token” for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually making the requests to the application.
  • Anytime you define a HTML form in your application, you should include a hidden CSRF token field in the form so that the CSRF protection middleware can validate the request.
  • You may use the @csrf Blade directive to generate the token field:
  • The VerifyCsrfToken middleware, which is included in the web middleware group, will automatically verify that the token in the request input matches the token stored in the session.
  • Any HTML forms pointing to POST, PUT, or DELETE routes that are defined in the web routes file should include a CSRF token field. Otherwise, the request will be rejected.<form class=”form” method=”post” action=”{{action(‘HakenBranchControllerTest@update’,[ ‘id’ => 7])}}” enctype=”multipart/form-data” >{{ csrf_field() }}

    @method(‘PUT’)

    <div class=”col-sm-9 offset-md-3″>

    <button type=”submit” class=”btn btn-success”>{{__(‘Update record’)}}</button>

    </div>

    </form>

    <form class=”form” method=”get” action=”{{action(‘HakenBranchControllerTest@action’,[ ‘name’ => ‘Laravel’])}}” enctype=”multipart/form-data” >

    {{ csrf_field() }}

    <div class=”col-sm-9 offset-md-3″>

    <button type=”submit” class=”btn btn-success”>{{__(‘Route Precedence’)}}</button>

    </div>

    </form>

    <form class=”form” method=”get” action=”{{route(‘admin’)}}” enctype=”multipart/form-data” >

    {{ csrf_field() }}

    <div class=”col-sm-9 offset-md-3″>

    <button type=”submit” class=”btn btn-success”>{{__(‘Route Precedence’)}}</button>

    </div>

    </form>

    <form class=”form” method=”get” action=”{{action(‘HakenBranchControllerTest@show’,[ ‘id’ => 7])}}” enctype=”multipart/form-data” >

    {{ csrf_field() }}

    <div class=”col-sm-9 offset-md-3″>

    <button type=”submit” class=”btn btn-success”>{{__(‘Show a record’)}}</button>

    </div>

    </form>

    <form class=”form” method=”get” action=”{{action(‘HakenBranchControllerTest@create’)}}” enctype=”multipart/form-data” >

    {{ csrf_field() }}

    <div class=”col-sm-9 offset-md-3″>

    <button type=”submit” class=”btn btn-success”>{{__(‘Add new record’)}}</button>

    </div>

    </form>

    <form class=”form” method=”get” action=”{{route(‘except’,[ ‘id’ => 7])}}” enctype=”multipart/form-data” >

    {{ csrf_field() }}

    <div class=”col-sm-9 offset-md-3″>

    <button type=”submit” class=”btn btn-success”>{{__(‘Add new record’)}}</button>

    </div>

    </form>

    Conclusion – Laravel provides support for RESTful APIs. Laravel scaffolding support for CRUD APIs helps to concentrate on business logic and fast development.

All search results