# Laravel Tutorial: Todo backend routing + Dingo API

Create backend routes + Dingo API

We make use of a package called Dingo for handling API requests. It is a full-fledged RESTful API package for Laravel and Lumen frameworks. This package makes it easy to create RESTful JSON APIs and also re-use the same code for rendering pages. This is useful when we need to re-render our React components on router navigation and need to consume the data via a JSON API without reloading the entire page. The complete documentation for Dingo API can be found here: https://github.com/dingo/api/wiki

To better understand this feature, let us first make some changes to the routes.php file. Open in your favorite editor laravel-todolist/app/Http/routes.php and replace the contents with the following code.


<?php

/*
|--------------------------------------------------------------------------
| Dingo API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the API routes for an application.
| You will later just reuse these API routes in your regular routes via an
| instance of the Dingo internal API dispatcher. This creates a consumable
| API allowing for reuse of application logic.
|
*/

$api = app('Dingo\Api\Routing\Router');

$api->version('v1', function ($api) {
  $api->get('todos', 'App\Http\Controllers\TodoController@index');
  $api->post('todos', 'App\Http\Controllers\TodoController@store');
  $api->get('todos/{id}', 'App\Http\Controllers\TodoController@show');
  $api->put('todos/{id}', 'App\Http\Controllers\TodoController@update');
  $api->delete('todos/{id}', 'App\Http\Controllers\TodoController@destroy');
});

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/

Route::get('/', function () {
  $dispatcher = app('Dingo\Api\Dispatcher');
  $data = [ "todos" => $dispatcher->version('v1')->get('todos') ];
  $content = React::renderMarkup([ "path" => '/',
                                     "data" => $data ]);

  return view('index', [ "content" => $content,
                           "data" => json_encode($data) ]);
});

Route::get('/todos/{id}', function ($id) {
  $dispatcher = app('Dingo\Api\Dispatcher');
  $data = [ "todo" => $dispatcher->version('v1')->get('todos/'.$id) ];
  $content = React::renderMarkup([ "path" => "/todos/".$id,
                                     "data" => $data ]);

  return view('index', [ "content" => $content,
                           "data" => json_encode($data) ]);
});

// Catch-All Route
Route::get('{path}', function ($path) {
  $data = "";
  $content = React::renderMarkup([ "path" => $path,
                                     "data" => $data ]);

  return view('index', [ "content" => $content,
                          "data" => json_encode($data) ]);
})->where('path', '(.*)');

Let's breakdown the above code. Firstly, the code itself is divided into 2 prominent sections: One which defines the Dingo API routes and the other which defines the Application routes.

In the Dingo API routes section we first define an API and the current version of the API (v1). Once defined, we create routes for every possibile RESTful action (CREATE, READ, UPDATE, DELETE).

These routes point to our TodoController's instance methods (index, store, show, update and destroy).

To verify if these routes have been configured properly or not, you can run the following command from your terminal/command prompt in the root of your laravel-todolist directory:

$ php artisan api:routes

The output would look something like this:

+------+----------+-----------------+------+---------------------------------------------+-----------+------------+----------+------------+
| Host | Method   | URI             | Name | Action                                      | Protected | Version(s) | Scope(s) | Rate Limit |
+------+----------+-----------------+------+---------------------------------------------+-----------+------------+----------+------------+
|      | GET|HEAD | /api/todos      |      | App\Http\Controllers\TodoController@index   | No        | v1         |          |            |
|      | POST     | /api/todos      |      | App\Http\Controllers\TodoController@store   | No        | v1         |          |            |
|      | GET|HEAD | /api/todos/{id} |      | App\Http\Controllers\TodoController@show    | No        | v1         |          |            |
|      | PUT      | /api/todos/{id} |      | App\Http\Controllers\TodoController@update  | No        | v1         |          |            |
|      | DELETE   | /api/todos/{id} |      | App\Http\Controllers\TodoController@destroy | No        | v1         |          |            |
+------+----------+-----------------+------+---------------------------------------------+-----------+------------+----------+------------+

You can even protect your routes with Basic Auth, JSON Web Tokens (JWT) or OAuth 2.0. However, this is beyond the scope of this tutorial. You can always refer to the Dingo API documentation for more information.

These API routes respond with JSON for GET requests. This is ideal when you need to fetch data via AJAX and don't want to clutter your main render routes with if-else blocks checking for AJAX headers.

In the Application routes section, we define 2 routes: One for rendering all todo items "/" and the other for rendering a specific todo item "/todos/{id}". As you can see, we re-use the same Dingo API routes we defined earlier by accessing it's internal dispatcher. The data is fetched by directly calling the dispatcher. You can read more about this feature here: https://github.com/dingo/api/wiki/Internal-Requests.

We then render the HTML markup by calling React::renderMarkup and pass it the current path along with the data we just fetched from the dispatcher. All routes should always render index.blade.php. The data and path received by the client side react-router will render the appropriate page.

We also finally define a catch-all route that is triggered when the path does not match any known route. This catch-all route should always be defined at the end of routes.php.

With this, we have finished implementing the backend for our Todo list app. The next section deals with creating a basic frontend using React and details how the frontend connects with the backend.