JSON APIs with Laravel: Part 3 - Controllers, Routing and Data Exposure cover image

JSON APIs with Laravel: Part 3 - Controllers, Routing and Data Exposure

Oliver Sarfas • July 30, 2019

programming laravel

This a part of my "JSON APIs with Laravel" series. If you've missed parts 1, or two, you can find them at the bottom of this article


Models? ✔

Data? ✔ (yeah it's fake, but it's data!)

URLS? 🔧 Let's do this!

No more long winded intros on this part, we're just going to jump right into the solution and get some data being exposed!


Controllers

Laravel follows the MVC approach to the Request Life Cycle. This part right here, is the C. We need to produce one, or many, controllers, that take our request, and return us something to view. In our case, it'll be JSON data, but this could be a HTML page, XML data, a csv file - whatever.

In the previous episode, we made our Contact model using the command line command php artisan make:model Contact --all, the -all was very important, as it produced us a ContactController that would help us "wire up the model" and expose it via endpoint(s).

So let's go into this ContactController and fill out the methods. Here's what the default scaffolding should look like;

For now, we're this episode, we're going to be looking at the index() and show() methods. We'll come to the rest next time.


Hooking up Data to our Controller

The index method is used to represent the B in BREAD. This will allow our users / clients, to Browse all the contacts in our application. As such, we need to return all of our Contacts.

In Laravel, this is done very simply, like so;

This will return a nice JSON headed response, with our contacts as an array of objects.

Now for the show method, which represents the R in BREAD, Read. Allowing someone consuming our API to show a single Contact, instead of all at once.

<?php

namespace App\\Http\\Controllers;

use App\\Contact;
use Illuminate\\Http\\Request;

class ContactController extends Controller
{

    [...]

    public function show(Contact $contact)
    {
        return response()->json($contact);
    }

    [...]
}

Once again, Laravel makes this very easy using it's response() method and Route Model Binding (Contact is typehinted in the method, more about this when it comes to Routing)

Routing

Right now, we've got some data, hooked up to a Controller with some methods; however there's no way of accessing this through a browser / API tool.

Let's go into our routes/web.php file, and create some routes then.

As standard, Laravel ships with the following routes/web.php file.

<?php

/*
|
| Web Routes
|
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the \u0022web\u0022 middleware group. Now create something great!
|
*/

Route::get('/', function(){
    return view('welcome');
});

Let's swap that out, and add in our ContactController as a Resource. This will automatically wire up all the BREAD routes to our controller, against a resource we specify, in this case it'll be a "contact". Our file should look like this;

<?php

Route::resource('contact', 'ContactController');

That's it. If you thought well that's too easy - that's the entire point of Laravel. It makes the Developer Experience simple.

We can check this by running php artisan route:list in our console, and see that our Routes are now registered.

$ a route:list name=contact

++-++-+++
| Domain | Method    | URI                    | Name            | Action                                         | Middleware |
++-++-+++
|        | GET|HEAD  | contact                | contact.index   | App\\Http\\Controllers\\ContactController@index   | web        |
|        | POST      | contact                | contact.store   | App\\Http\\Controllers\\ContactController@store   | web        |
|        | GET|HEAD  | contact/create         | contact.create  | App\\Http\\Controllers\\ContactController@create  | web        |
|        | GET|HEAD  | contact/{contact}      | contact.show    | App\\Http\\Controllers\\ContactController@show    | web        |
|        | PUT|PATCH | contact/{contact}      | contact.update  | App\\Http\\Controllers\\ContactController@update  | web        |
|        | DELETE    | contact/{contact}      | contact.destroy | App\\Http\\Controllers\\ContactController@destroy | web        |
|        | GET|HEAD  | contact/{contact}/edit | contact.edit    | App\\Http\\Controllers\\ContactController@edit    | web        |
++-++-+++

Our endpoints are now live, at /contact and /contact/{contact}.

In this instance, {contact} is the id of the contact we'd like to see. This is resolved using Laravel's Route Model Binding.

Next time

We'll move onto the other methods in our ContactController and how we process those. We've already got BR done in BREAD, the next steps are E, A, and D. How we validate our data, store it, and how we serve errors to the user in the event something went wrong.

Following that, we'll look at authentication and basic Policy based permissions.

Previous Episodes

Episode 1

Episode 2