thewhitefox

theWhiteFox design & build web apps

thewhitefox

Laravel Api

2021 January 31st

Now to build a RESTful application programming interface (API) using Laravel 8.x learning-by-doing. REST stands for REpresentational State Transfer.

As mobile development and JavaScript frameworks become more popular, even the norm, so it's nessarary to learn how RESTful APIs work. Laravel an open-source PHP model–view–controller (MVC) web framework, created by Taylor Otwell, is an opinionated PHP application framework as apposed to for example ExpressJS a minimal, un-opinionated JavaScript framework of which I will cover in another post.

In this post I am going to a build an MVC - Web API with user authentination / registeration, login to a MySql DataBase (DB) using an .env file. I will also test with Laravel testing PHPUnit

In this post I am going to a build an MVC App single interface with a user login to a MySql DataBase (DB). Feel free to explore / reference / download / clone or fork the repo GitHub

HTTP VerbCRUDEntire Collection (e.g. /users)Specific Item (e.g. /user/{id})
POSTCreate201 (Created), 'Location' header with link to /users/{id} containing new ID.404 (Not Found), 409 (Conflict) if resource already exists..
GETRead200 (OK), list of users. Use pagination, sorting and filtering to navigate big lists.200 (OK), single user. 404 (Not Found), if ID not found or invalid.
PUTUpdate/Replace405 (Method Not Allowed), unless you want to update/replace every resource in the entire collection.200 (OK) or 204 (No Content). 404 (Not Found), if ID not found or invalid.
PATCHUpdate/Modify405 (Method Not Allowed), unless you want to modify the collection itself. 200 (OK) or 204 (No Content).404 (Not Found), if ID not found or invalid.
DELETEDelete405 (Method Not Allowed), unless you want to delete the whole collection—not often desirable.200 (OK). 404 (Not Found), if ID not found or invalid.

Getting set up

First install Get Composer a dependency manager for PHP. After composer installation run the below commands in your cli. For my cli I use ohmyz

1$ composer global require laravel/installer
2$ laravel new myapp
3$ php artisan serve

Laravel localhost development server started:

1http://127.0.0.1:8000

Laravel App

Install MySQL, if using MacOS or Linux I recommend using https://brew.sh/ then run the below command.

1brew services start mysql

Create a DB for this app, credentials are in the .env the file located in the root of your project.

1DB_CONNECTION=mysql
2DB_HOST=127.0.0.1
3DB_PORT=3306
4DB_DATABASE=myapp
5DB_USERNAME=root
6DB_PASSWORD=

I am using Migrate, it's like version control for our DB read more here Laravel 8.x Migrations

jsx php artisan make:model Article -m

After running the above go to the migrations folder there should be a file like this 2021_01_31_170103_create_articles_table.php To get up and running we need dummy data, I am seeding the DB with data so lets seed. Want to learn more about writing seeders read https://laravel.com/docs/8.x/seeding

1php artisan make:seeder ArticlesTableSeeder
1<?php
2
3namespace Database\Seeders;
4
5use Illuminate\Database\Seeder;
6
7class ArticlesTableSeeder extends Seeder
8{
9 /**
10 * Run the database seeds.
11 *
12 * @return void
13 */
14 public function run()
15 {
16 // lets: truncate our existing records to start from scratch
17 Article:truncate();
18
19 $faker = \Faker\Factory::create();
20
21 // lets create some articles in our DB
22 for($i = 0; $i < 50; $i++) {
23 Article::create([
24 'title' => $faker->sentence,
25 'body' => $faker->paragraph
26 ]);
27 }
28 }
29}
1php artisan make:seeder UsersTableSeeder

Database Seeding

A quick way to populate our myapp DB.

Routes and Controllers

https://laravelpackage.com/09-routing.html

Testing the Endpoints

Laravel lucky for us comes with PHPUnit ready to rock. Testing support with PHPUnit is installed by default with a phpunit.xml file, a root tests folder and a bunch of helper methods already set up for our application. Create the test folder (if it does not exist) then create TestController inside. https://stackoverflow.com/a/43674716/1967126 basic endpoints for our application: create, retrieve the list, retrieve a single one, update, and delete. On the routes/api.php file, we can simply do this:

1php artisan make:controller Article/ArticleController

HTTP Status Codes and the Response Format

Sending a Correct 404 Response Laravel Errors

1<?php
2
3namespace App\Exceptions;
4
5use Throwable;
6use Illuminate\Auth\AuthenticationException;
7use Illuminate\Database\Eloquent\ModelNotFoundException;
8use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
9
10
11class Handler extends ExceptionHandler
12{
13 /**
14 * A list of the exception types that are not reported.
15 *
16 * @var array
17 */
18 protected $dontReport = [
19 //
20 ];
21
22 /**
23 * A list of the inputs that are never flashed for validation exceptions.
24 *
25 * @var array
26 */
27 protected $dontFlash = [
28 'password',
29 'password_confirmation',
30 ];
31
32
33 public function render($request, Throwable $exception) {
34 // replace 404 with a json response
35 if ($exception instanceof ModelNotFoundException &&
36 $request->wantsJson())
37 {
38 return response()->json([
39 'error' => 'Resource not found'
40 ], 404);
41 }
42
43 return parent::render($request, $exception);
44 }
45
46 /**
47 * Register the exception handling callbacks for the application.
48 *
49 * @return void
50 */
51 public function register()
52 {
53 $this->renderable(function(InvalidOrderException $e, $request) {
54 return response()->json([
55 'error' => 'resource not found'
56 ], 404);
57 });
58
59 $this->reportable(function (Throwable $e) {
60 //
61 });
62 }
63}

Reference

Laravel 8.x Handler.php return a JSON response, in Laravel 8x, render exceptions in the register() method. Laravel Errors: Rendering Exceptions

Laravel errors configuration

API throttling and Authenication middleware: https://laravel.com/docs/8.x/middleware

Closure https://stackoverflow.com/a/47348663/1967126

Bugs

Laracasts.com/discuss/channels/laravel/laravel7 add Throwable

if you run into an issue like I did, having a prevoius installed version of MySQL here is the solution I used https://stackoverflow.com/a/6378429/1967126

I am using Migrate it's like version control for our DB read more here Laravel 8.x Migrations

Laravel passport

php artisan make:migration --table=users adds_api_token_to_users_table

Laravel.com authentication

Medium simple authentication Laravel 8

Laravel frontend introduction npm install && npm run dev php artisan ui vue --auth

Laravel App

Toptal RESTful Laravel API tut

Laravel Docs Quick

Laravel Docs 8.x

Laracasts MySql

Riptutorial creating seeder

free web hosting

Techradar: best free web hosting

InfinityFree

https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes

https://phpunit.readthedocs.io/en/9.0/

https://laravel.com/docs/8.x/dusk

APIs