Are you building an API? If you are, chances are you’ll want it to have: RESTful endpoints security and authentication JSON responses with HTTP status codes Laravel offers all of this out of the box. It also has excellent documentation and an active community offering tips and writing articles like this one. This is why I keep coming back to Laravel time and again. In this article I’m going to walk you through the steps required to build a REST API with Laravel. I’m going to start right at the beginning — creating a Laravel project — and will cover everything needed to build a functioning API. I’ll also cover related issues such as how to structure your endpoints and what form your responses should take. I’m assuming you already have a webserver, PHP and a database up and running. Let’s dive in. Install and configure Laravel Install Composer Composer is a tool for dependency management in PHP. Don’t worry about exactly what that means. The bottom line is that it’s the simplest way to create a Laravel project. There are instructions for installing Composer . You can read the instructions but you don’t really need to. Just punch this address into a browser: here https://getcomposer.org/installer and save the file to the parent directory of which your Laravel project directory will be a child. For example, if you have a directory which will contain your Laravel project directory, you should save in the directory. installer Sites installer Sites Then, on the command line, navigate to the directory and run the installer like this: Sites php installer You’ll now see another file in the directory: . What you’ve done is install Composer locally, meaning that to use it you need to navigate to the directory in which it is located before issuing commands. You can move or copy to other directories — it’s not tied to the directory in which it was originally installed. composer.phar composer.phar Alternatively you can install Composer globally, which will allow you to issue commands from anywhere on your system. The installation instructions linked to above tell you how to do that. Now that Composer is installed, you can delete the installer if you like: MacOS or Unix: rm installer Windows: del installer Create a Laravel project As recommended on the Laravel , you can create a new Laravel project with this command: installation page composer create-project — prefer-dist laravel/laravel restapi There are a few things to note about this: This will likely take a couple of minutes and may at first appear not to be doing anything. Be patient. This command assumes you have Composer installed globally. If not, instead of ‘composer’ you’ll need to type ‘php composer.phar’. So the full command will be: php composer.phar create-project --prefer-dist laravel/laravel restapi This will create a new directory into which Laravel will be installed. If you installed Composer locally, copy and paste into . We’ll need to run Composer commands from within the directory a bit later on. restapi composer.phar restapi Laravel should now be installed and working. You can test it by entering the file path for into a browser address bar. The full path will be something like this: restapi/public/ http://localhost/... /restapi/public/ You should now see the Laravel welcome page: Screenshot — Laravel welcome page If instead you get a permission denied error, there’s a fix for that . Once you’ve run the fix, try the page again. It should now be working. here Set up your database connection Find the file within the root of your project directory. It may be hidden by default. If it is, do one of the following: .env press ‘command’ + ‘shift’ + ‘.’ Finder (MacOS): see File Explorer (Windows): these instructions type ‘ls -a’ Terminal (MacOS): type ‘dir /A’ Command line (Windows): Now open in a code editor and find this section of the file: .env DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=homesteadDB_USERNAME=homesteadDB_PASSWORD=secret Replace the default values with those applicable to your set up. I’m using MySQL with a standard set up, so for me the only values that require changing are the last three: DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=name_of_dbDB_USERNAME=name_of_userDB_PASSWORD=password Set up Laravel user authentication There are instructions for doing this , and it’s all pretty easy. On the command line, make sure you’re in your project directory and run these two commands: here php artisan make:authphp artisan migrate The first command adds a few views to your project that enable your users to register, login and reset their password. You can take a look at these yourself by visiting: http://localhost/... / restapi/public/register http://localhost/... / restapi/public/login http://localhost/... / restapi/public/reset The second command adds two tables to your database: name, email, password (hashed), etc for your users users: used to store password reset codes password_resets: Set up Laravel Passport As of version 5.8, Laravel ships with a default API authentication scheme that involves generating and inspecting a random token assigned to your application. This is not a robust solution and Laravel recommends instead using Laravel Passport to handle API authentication for production applications. That’s exactly what we’re going to do. Setting up Laravel passport is a little more involved than setting up user authentication, but it’s not too hard. You can take a look at the official instructions . here From your project directory run these three commands: php composer.phar require laravel/passportphp artisan migratephp artisan passport:install The first command installs Laravel Passport (which may take a few minutes), the second creates some required database tables and the third creates the encryption keys needed to generate secure access tokens. Next you need to alter four files that ship with Laravel. The first is . This is your User model. Models are Laravel’s way of mapping classes to underlying database tables. The parts of that you need to add or alter are in bold. restapi/app/User.php User.php <?phpnamespace App;use Laravel\Passport\HasApiTokens;use Illuminate\Notifications\Notifiable;use Illuminate\Foundation\Auth\User as Authenticatable;class User extends Authenticatable{use HasApiTokens, Notifiable;} The second is . This is where you register and run services for your application, such as Laravel Passport. restapi/app/Providers/AppServiceProvider.php <?phpnamespace App\Providers;use Laravel\Passport\Passport;use Illuminate\Support\Facades\Gate;use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;class AuthServiceProvider extends ServiceProvider{/** * The policy mappings for the application. * * @var array */ protected $policies=[ 'App\Model'=> 'App\Policies\ModelPolicy',]; /** * Register any authentication / authorization services. * * @return void */ public function boot() {$this->registerPolicies(); Passport::routes();}} The third is , which contains authentication configuration options for your Laravel instance. restapi/config/auth.php 'guards'=> [ 'web'=> [ 'driver'=> 'session', 'provider'=> 'users',], 'api'=> [ 'driver'=> 'passport', 'provider'=> 'users',],], The last is , which contains various middleware settings for your Laravel instance. Middleware is discussed in a little more detail below. restapi/app/Http/Kernal.php 'web'=> [ // Other middleware... \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,], Laravel Passport is now set up. It’s time to build our API. Building our API What is a RESTful API endpoint? An API endpoint is a URL that, when called, performs some action against a resource, such as a database. To be RESTful, an API endpoint must adopt a certain design pattern. For our purposes this means it should: For example, the endpoint should perform actions against resources relating to cars. Note that we have included the API version number ‘v1’ in the path. This is good practice as it enables you to update your API in the future while retaining backwards compatibility. Have a descriptive URL: http://localhost/... / restapi/public/api/v1/cars Typically GET (to return records), POST (to create new records), PUT (to amend records) and DELETE (to delete records). Utilise one or more HTTP verbs: This should be a representation of the state of the resource, usually records in a database. Typically it is returned in JSON format, although other formats are possible. Return data: With this in mind, let’s create our first API endpoint. Creating an API endpoint The first thing we need to do is create a route for our endpoint. Think of a route as a URL. For example, the route ‘/example’ would be accessible by visiting in a browser. http://localhost/... / restapi/public/example Laravel ships with a folder which contains files for different types of routes. For example, contains web routes (ie. routes you can reach via a web browser) and contains API routes (ie. routes you can reach via API calls). Since we’re creating an API route, open and add the following after the existing content: restapi/routes web.php api.php api.php Route::get('/v1/cars', function (Request $request) {return 'From the server: details of two cars';}); And… that’s it, we have our first API endpoint! Testing our new API endpoint To test our new API endpoint we’re going to need to set up our application to make and receive an API call. In a web app this is typically done via Javascript, which is how we’ll do it here. Open . This is a template used by a number of pages throughout the application, including the login, registration and home pages. Add the following immediately after the opening BODY tag: restpi/resources/views/layouts/app.blade.php <div id="response"> API response here</div><script> fetch('api/v1/cars') .then(function(response) {response.text().then(function(data) {document.getElementById('response').innerHTML=data;});}) .catch(function(err) {console.log('Error: ' + err);});</script> We’ve done two things here: ‘ ’ This is where we will show our API responses. Added a DIV with id= response : This uses the Javascript method to call our API and, if successful, handle the response by injecting it into the DIV. Added a SCRIPT tag containing some Javascript: fetch() Now navigate your browser to . You should see the words ‘From the server: details of two cars’ in the top left corner of the page. Our API endpoint is working! http://localhost/... / restapi/public/login Returning JSON At the moment our API endpoint is returning plain text. Ideally it should return JSON, which we can do by amending as follows: restapi/routes/api.php Route::get('/v1/cars', function (Request $request) {return response()->json([ 'cars'=> [ 'registration'=> 'ABC001', 'dateRegistered'=> '2019-01-01', 'color'=> 'black', 'make'=> 'tesla', 'model'=> 's']], 200);}); Our API is now returning JSON. Notice that we are also setting the HTTP status code to 200, indicating that the request was successful. When returning JSON, especially when handling errors, you should take care to use the correct HTTP status code. Common ones are 400, indicating a bad request (eg. a parameter was missing or was incorrectly formatted), and 404, indicating that the requested resource was not found. A full list of HTTP status codes is . I recommend taking a look at 418. here To test our new endpoint we need to update the script that we added to to handle JSON responses: restpi/resources/views/layouts/app.blade.php <script> fetch('api/v1/cars') .then(function(response) {response.json().then(function(data) {var str=JSON.stringify(data.cars); document.getElementById('response').innerHTML=str;});}) .catch(function(err) {console.log('Error: ' + err);});</script> Refresh and you should now see the details of the car in top left corner of the page. http://localhost/... / restapi/public/login Our new endpoint works just fine but it has a couple of limitations. Firstly, it does not require authentication, meaning it is accessible to the whole world. Secondly, any programming logic required to return results must go in the routing file , which is not the best place for it. Let’s rectify these issues now. api.php Adding authentication Update the code in as follows: api.php Route::middleware('auth:api')->get('/v1/cars', function (Request $request) {return response()->json([ 'cars'=> [ 'registration'=> 'ABC001', 'dateRegistered'=> '2019-01-01', 'color'=> 'black', 'make'=> 'tesla', 'model'=> 's']], 200);}); We’ve added the API authentication middleware to our route. You can read about middleware . Essentially it is code that runs “in the middle” — between receipt of an incoming request and your own code attached to the route. The API authentication middleware checks that an incoming API request is authenticated, which requires: here CSRF is an acronym for “cross-site request forgery”. It’s an exploit involving data being sent to the server from an unexpected source. Including a CSRF token in all requests coming from a webpage is a way to avoid CSRF attacks. CSRF token: When a user logs in, Laravel sets a session cookie to identify and authentic the user. The cookie is automatically attached by the browser to outgoing requests. Laravel session cookie: To include a CSRF token in the page, go back in to and add the following anywhere inside the HEAD section: restpi/resources/views/layouts/app.blade.php <meta name="csrf-token" content="{{csrf_token()}}"> is a Laravel function that, you guessed it… generates a CSRF token. We can now update our Javascript to ensure that this token is included in all API requests coming from the page: csrf_token() <script> fetch('api/v1/cars',{headers:{'x-csrf-token' : document.querySelector("meta[name='csrf-token']").getAttribute("content")}}) .then(function(response) {response.json().then(function(data) {var str=JSON.stringify(data.cars); document.getElementById('response').innerHTML=str;});}) .catch(function(err) {console.log('Error: ' + err);});</script> Now all we need to do is create a user account and log in. Go to . You should see ‘API response here’ in the top left corner of the page, indicating that the API request has failed. The page is calling your API endpoint but no response is received because you are not authenticated. http://localhost/... / restapi/public/register Create an account using the form on the registration page. Use any credentials you like — they will be stored in your local database. Once the account is created Laravel will log you in and redirect you to . You should now see the car details in the top left corner of the page, received via a successful API request. http://localhost/... / restapi/public/home Moving logic to the right place Recall that the route associated with our API endpoint looks like this: Route::middleware('auth:api')->get('/v1/cars', function (Request $request) {return response()->json([ 'cars'=> [ 'registration'=> 'ABC001', 'dateRegistered'=> '2019-01-01', 'color'=> 'black', 'make'=> 'tesla', 'model'=> 's']], 200);}); This is returning static data. In a real-world application we would likely want to retrieve details of one or more cars from the database. We would probably also want to allow the user to specify which cars they want to retrieve via parameters attached to the endpoint. This adds complexity and requires programming logic, which should be handled in a Controller rather than in the routing file. Let’s fix this now. On the command line enter the following to create a Controller: php artisan make:controller Controller_Cars Laravel will create the Controller for you in this file . Open it and add a new public method to the class. The class should look like this: restapi/app/Http/Controllers/Controller_Cars.php get() Controller_Cars class Controller_Cars extends Controller{public function get(Request $request) {}} Now we can copy the programming logic from our route into this method, and call the method from the route, like this: get() restapi/app/Http/Controllers/Controller_Cars.php: public function get(Request $request) {return response()->json([ 'cars'=> [ 'registration'=> 'ABC001', 'dateRegistered'=> '2019-01-01', 'color'=> 'black', 'make'=> 'tesla', 'model'=> 's']], 200);} restapi/routes/api.php: Route::middleware(['auth:api'])->get('/v1/cars', 'Controller_Cars@get'); Refresh and you should once again see the details of the car, only this time it’s coming from . Any programming logic associated with the API endpoint can now go in the Controller, where it belongs. http://localhost/... / restapi/public/home Controller_Cars Structuring your application Suppose you are building an API that deals with resources relating to both cars and motorbikes. Chances are you need endpoints to handle creating, retrieving, updating and deleting records. A RESTful implementation of this API might have these endpoints and methods: yoursite.com/api/v1/cars: POST: Creates records of cars GET: Retrieves records of cars PUT: Updates records of cars DELETE: Deletes records of cars yoursite.com/api/v1/motorbikes: POST: Creates records of motorbikes GET: Retrieves records of motorbikes PUT: Updates records of motorbikes DELETE: Deletes records of motorbikes And you could implement this as follows: yoursite/routes/api.php: Route::middleware(['auth:api'])->group(function () {Route::post('/v1/cars', 'Controller_Cars@post'); Route::get('/v1/cars', 'Controller_Cars@get'); Route::put('/v1/cars', 'Controller_Cars@put'); Route::delete('/v1/cars', 'Controller_Cars@delete'); Route::post('/v1/motorbikes', 'Controller_Motorbikes@post'); Route::get('/v1/motorbikes ', 'Controller_ Motorbikes @get'); Route::put('/v1/motorbikes ', 'Controller_ Motorbikes @put'); Route::delete('/v1/motorbikes ', 'Controller_ Motorbikes @delete');} Notice that we are using a route group to attach the API authentication middleware to all routes included in the group. yoursite/app/Http/Controllers/Controller_Cars.php: public function post(Request $request) {// code to create records of cars}public function get(Request $request) {// code to retrieve records of cars}public function put(Request $request) {// code to update records of cars}public function delete(Request $request) {// code to delete records of cars} yoursite/app/Http/Controllers/Controller_Motorbikes.php: public function post(Request $request) {// code to create records of motorbikes}public function get(Request $request) {// code to retrieve records of motorbikes}public function put(Request $request) {// code to update records of motorbikes}public function delete(Request $request) {// code to delete records of motorbikes} Conclusion In this article we’ve covered everything you need to build a RESTful API with Laravel. Now it’s up to you to flesh it out with actual code. That’s the fun part — happy coding! Thanks so much for reading! If you liked this article, please leave a clap and consider following me. I’d also love to hear your thoughts in the comments below. Check out my latest project: . Lithium List Follow me on . Twitter