JSON APIs with Laravel: Part 3 - Controllers, Routing and Data Exposure
Oliver Sarfas • July 30, 2019
programming laravelThis 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.