All Projects → connor11528 → laravel-api-example

connor11528 / laravel-api-example

Licence: other
💻 Build an API with Laravel 5

Programming Languages

PHP
23972 projects - #3 most used programming language
HTML
75241 projects
Vue
7211 projects

Projects that are alternatives of or similar to laravel-api-example

teamo-ddd-example
Implementing Domain Driven Design in PHP using Laravel
Stars: ✭ 46 (-2.13%)
Mutual labels:  laravel-framework, laravel-application, laravel5
december-2018-meetup
🤖 Build an API with Laravel 5.7
Stars: ✭ 27 (-42.55%)
Mutual labels:  laravel-application, laravel5, laravel-api
Learn Laravel
Laravel 学习资料和开源项目集
Stars: ✭ 229 (+387.23%)
Mutual labels:  laravel-framework, laravel-application, laravel5
opencore
OpenCore - Laravel for OpenCart
Stars: ✭ 42 (-10.64%)
Mutual labels:  laravel-framework, laravel-application, laravel5
Blogetc
Easily add a full Laravel blog (with built in admin panel and public views) to your laravel project with this simple package.
Stars: ✭ 198 (+321.28%)
Mutual labels:  laravel-framework, laravel-application
solder
Supercharge Your Modpack with Solder
Stars: ✭ 27 (-42.55%)
Mutual labels:  laravel5, laravel55
Auth Tests
Always-current tests for Laravel's authentication system. Curated by the community.
Stars: ✭ 230 (+389.36%)
Mutual labels:  laravel-framework, laravel5
Laravel-5.3-Repository
Simple repository setup for Laravel 5.3
Stars: ✭ 17 (-63.83%)
Mutual labels:  laravel-framework, laravel5
advance-blog-in-laravel-5.5-in-tdd
build blog with cool feature like Activity feed, Filter post, post subscription, mentioned user, notification, search with Algolia
Stars: ✭ 11 (-76.6%)
Mutual labels:  laravel-framework, laravel5
Laracrud
Laravel Code Generator based on MySQL Database
Stars: ✭ 238 (+406.38%)
Mutual labels:  laravel-framework, laravel-application
Adware-ads-network-server
Online Advertising Network Server
Stars: ✭ 44 (-6.38%)
Mutual labels:  laravel-framework, laravel-application
Laravel Qrcode Ecommerce
This is a complete laravel project that handles qrcodes, payments, api/microservices, and ecommerce
Stars: ✭ 36 (-23.4%)
Mutual labels:  laravel-framework, laravel-application
Laravel Restaurant Pos
Restaurant POS
Stars: ✭ 27 (-42.55%)
Mutual labels:  laravel-framework, laravel5
Segnalibro
Save and comment your favorite links from the web. It's just a bookmarking application.
Stars: ✭ 14 (-70.21%)
Mutual labels:  laravel5, laravel55
laration
Simple package to see all current configurations being used by your Laravel application
Stars: ✭ 47 (+0%)
Mutual labels:  laravel-application, laravel55
Coreui Free Laravel Admin Template
CoreUI Free Laravel Bootstrap Admin Template
Stars: ✭ 353 (+651.06%)
Mutual labels:  laravel-framework, laravel-application
Laravel Gitscrum
GitScrum is a Project Management Tool, developed to help entrepreneurs, freelancers, managers, and teams Skyrocket their Productivity with the Agile methodology and Gamification.
Stars: ✭ 2,686 (+5614.89%)
Mutual labels:  laravel-framework, laravel-application
laravel-docker-k8s
Laravel using Docker and Kubernetes
Stars: ✭ 60 (+27.66%)
Mutual labels:  laravel-framework, laravel5
pretty-routes
Display your Laravel routes in the console, but make it pretty. 😎
Stars: ✭ 627 (+1234.04%)
Mutual labels:  laravel-framework, artisan
Laravel-Trik-Indonesia
Kumpulan trik laravel berbahasa indonesia
Stars: ✭ 74 (+57.45%)
Mutual labels:  laravel-framework, laravel-application

Laravel 5 REST API

Build an API with Laravel 5

I'll be working alongside this tutorial for building the API. The author put the source code up for it here

Step 1: Create the project

We can use this handy script for generating a new Laravel 5 app.

I also wrote this Medium article that goes through installing and configuring a MySQL database for a Laravel 5 application. I find myself refering back to it regularly.

Step 2: Configure database and make models

If you don't have MySQL installed on Mac may the force be with you. It comes preinstalled and there's MAMP but getting your machine set up to run SQL to MySQL from the terminal can be tricky.

My setup is to run:

$ mysql -uroot -p 
> create database MY_APP_NAME;
$ php artisan make:model Article -m

The ; is required in order to end all SQL statements.

Add a title and body string columns to the articles database and run the migrations:

$ php artisan migrate

If you get an error saying cannot connect to homestead, even after you updated your .env to not point to homestead anymore clear the config and try again.

To clear config in Laravel:

$ php artisan config:clear

Make the models fillable (Laravel will protect them by default). Add this line to app/Article.php:

protected $fillable = ['title', 'body'];

Fillable will allow reads and writes to those database columns. You could also set a guarded property to an empty array:

$guarded = []

Which for our purposes will do the same thing. To learn more about this you can check the Eloquent docs on Mass Assignment.

Step 3: Step up a database seeders

By default we want data to play with so we must seed the database. Generate a new seeder for creating articles:

Create the articles table seeder:

$ php artisan make:seeder ArticlesTableSeeder

That file is in database/seeds/ArticlesTableSeeder.php. Update it so it looks like:

<?php

use App\Article;
use Illuminate\Database\Seeder;

class ArticlesTableSeeder extends Seeder
{
    public function run()
    {
        // Let's truncate our existing records to start from scratch.
        Article::truncate();

        $faker = \Faker\Factory::create();

        // And now, let's create a few articles in our database:
        for ($i = 0; $i < 50; $i++) {
            Article::create([
                'title' => $faker->sentence,
                'body' => $faker->paragraph,
            ]);
        }
    }
}

Run the database seeder:

$ php artisan db:seed --class=ArticlesTableSeeder

To make sure it worked we can use the artisan tinker command. For the uninitiated there's a great intro article about the tool on scotch.io.

To use it we run:

$ php artisan tinker 
> App\Article::all();

Fifty articles in JSON format should fill up your console screen. Congrats we seeded the database full of articles!

We'll do nearly the same thing for the users table and then call both seeders from database/seeds/DatabaseSeeder.php:

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call(ArticlesTableSeeder::class);
        $this->call(UsersTableSeeder::class);
    }
}

We'll be able to populate both database tables by running php artisan db:seed.

The full users table seeder in **database/seeds/UsersTableSeeder.php` looks like:

<?php

use Illuminate\Database\Seeder;
use App\User;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // Let's clear the users table first
        User::truncate();

        $faker = \Faker\Factory::create();

        // Let's make sure everyone has the same password and 
        // let's hash it before the loop, or else our seeder 
        // will be too slow.
        $password = Hash::make('toptal');

        User::create([
            'name' => 'Administrator',
            'email' => '[email protected]',
            'password' => $password,
        ]);

        // And now let's generate a few dozen users for our app:
        for ($i = 0; $i < 10; $i++) {
            User::create([
                'name' => $faker->name,
                'email' => $faker->email,
                'password' => $password,
            ]);
        }
    }
}

Step 4: Set up CRUD routes and controllers

Laravel follows the Model View Controller (MVC) pattern that was first popularized by Ruby On Rails. We have our models set up, now we're going to set up routes that map to controllers in order to send out JSON to people (ie Javascript engines or mobile phones) that make requests to our API.

$ php artisan make:controller ArticleController -r

In routes/api.php define our endpoints:

Route::get('articles', 'ArticleController@index');
Route::get('articles/{article}', 'ArticleController@show');
Route::post('articles', 'ArticleController@store');
Route::put('articles/{article}', 'ArticleController@update');
Route::delete('articles/{article}', 'ArticleController@delete');

We're going to take advantage of Route Model Binding so that instead of passing the id and fetching by id we straight up get the resource that we want. Here is what app/Http/Controllers/ArticleController.php looks like w/out the comments:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Article;

class ArticleController extends Controller
{
    public function index()
    {
        return Article::all();
    }

    public function show(Article $article)
    {
        return $article;
    }

    public function store(Request $request)
    {
        $article = Article::create($request->all());

        return response()->json($article, 201);
    }

    public function update(Request $request, Article $article)
    {
        $article->update($request->all());

        return response()->json($article, 200);
    }

    public function delete(Article $article)
    {
        $article->delete();

        return response()->json(null, 204);
    }
}

Now we have a rudimentary API for articles. You can view in your browser all the articles: http://localhost:8000/api/articles or an individual article based on id: http://localhost:8000/api/articles/2

Step 5: Test our API with Postman

Install the Postman client here

Postman website home page

From the postman client we can create get, put, post and delete requests with parameters and later on even add authorization headers. It took me a few minutes to get comfortable with their dashboard but I grew to digg it quickly. I'd heard about Postman for a long time but for whatever reason haven't incorporated it into my dev workflow. For building APIs Postman is a great tool!

Postman docs on making requests

Each request belongs to a collection so I made a test collection and defined some endpoints.

Postman initial route endpoints

You can view the API routes that I develop in this tutorial through this link

Easily share api endpoints you set up in Postman

Step 6: Customize error messages (optional)

By default when a route is not found Laravel will send an HTML page that says 404 we can't find this route. If we're building an API we want to send the user JSON they can use instead of a fat HTML chunk.

Redefine the render function in app/Exceptions/Handler.php:

    public function render($request, Exception $exception)
    {
        // This will replace our 404 response with
        // a JSON response.
        if ($exception instanceof ModelNotFoundException) {
            return response()->json([
                'error' => 'Resource not found'
            ], 404);
        }

        return parent::render($request, $exception);
    }

The header for specifying JSON responses is Accept: application/json

Step 7: Authentication

Add register, login and logout API routes:

Route::post('register', 'Auth\RegisterController@register');
Route::post('login', 'Auth\LoginController@login');
Route::post('logout', 'Auth\LoginController@logout');

These controllers are in the app/Http/Controllers/Auth directory and ship by default with Laravel 5.

In order to implement them for an API customization required. Define the register function in app/Http/Controllers/Auth/RegisterController.php:

protected function registered(Request $request, $user)
{
    $user->generateToken();
    return response()->json(['data' => $user->toArray()], 201);
}

And we define the generateToken function on the user model in app/User.php:

public function generateToken()
{
    $this->api_token = str_random(60);
    $this->save();
    return $this->api_token;
}

This generates a random string that we save for the user as their unique API token.

We can test this using postman on send a curl request like so:

$ curl -X POST http://localhost:8000/api/register \
 -H "Accept: application/json" \
 -H "Content-Type: application/json" \
 -d '{"name": "John", "email": "[email protected]", "password": "toptal123", "password_confirmation": "toptal123"}'

In the LoginController.php define a login method:

public function login(Request $request)
{
    $this->validateLogin($request);

    if ($this->attemptLogin($request)) {
        $user = $this->guard()->user();
        $user->generateToken();

        return response()->json([
            'data' => $user->toArray(),
        ]);
    }

    return $this->sendFailedLoginResponse($request);
}

This overwrites the trait defined in AuthenticatesUsers. Curl request to test login:

$ curl -X POST localhost:8000/api/login \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -d "{\"email\": \"[email protected]\", \"password\": \"toptal\" }"

Authorization token will be in the header for requests and look like Authorization: Bearer Jll7q0BSijLOrzaOSm5Dr5hW9cJRZAJKOzvDlxjKCXepwAeZ7JR6YP5zQqnw

Resources


Update 04/06/18: Token based authentication for a Laravel and React.js app (uses tymon/jwt-auth package): https://medium.com/@Gbxnga/token-based-authentication-with-react-and-laravel-restful-api-83f16581e85

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].