Build REST API with Laravel
https://ift.tt/3d64faz
With the rise of Mobile Development and JavaScript frameworks, using a RESTful API is the best option to build a single interface between your data and your client.
PHP has been the most popular web language in the present times by being simple to maintain, and quick to create feature-rich web applications. Websites that are dynamic, interactive, secure, and efficient need a powerful toolset to create and consume APIs.
In this article, you will learn how to build a modern RESTful API in Laravel.
Now let’s look at building a PHP RESTful API with Laravel.
Table of Contents:
- Prerequisites
- Understanding Our Application
- Setup New Laravel App
- Create MySQL Database
- Create Model and Migration
- Create Controller and Request
- Setup CRUD (Create, Read, Update and Delete)
Step 1: Prerequisites
Let’s look at these technologies as we build our API:
Step 2: Understanding Our Application
You will build a CRUD API. CRUD means Create, Read, Update, and Delete. Our API will have the following endpoints:
Method | URI | Name | Description |
---|---|---|---|
GET | api/posts | Index | All posts return. |
GET | api/posts/{id} | Show | Detail of a particular post by ID. |
POST | api/posts | Store | Create a new post. |
PUT | api/posts/{id} | Update | Update a particular post by ID. |
DELETE | api/posts/{id} | Destroy | Delete a particular post by ID. |
Step 3: Setup New Laravel App
To get started, create a Laravel application. To do this, run the following command in your terminal:
composer create-project laravel/laravel rest-api
or, if you have installed the Laravel Installer as a global composer dependency:
laravel new rest-api
Next, start up the Laravel server if it’s not already running:
php artisan serve
You will visit your application on http://localhost:8000.
Step 4: Create MySQL Database
Create a new database for your application.
Login into MySQL and run the following command:
mysql -u<username> -p<password>
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1791
Server version: 8.0.22-0ubuntu0.20.04.3 (Ubuntu)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
For Create a new Database, run the following command:
CREATE DATABASE `rest-api`;
Step 5: Create Model and Migration
We can create a Model along with migration, run the following command:
php artisan make:model Post -m
-m this argument will create Migration in Single Command.
A new file named Post.php will be created in the app directory.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = 'posts';
protected $fillable = [
'name',
'image',
'description'
];
}
A migration file will be created in the database/migrations directory to generate the table in our database. Modify the migration file to create a column for name, description, and image, these all are fields that accept string value.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('image');
$table->text('description');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
Open the .env file and update the credentials to access your MySQL database:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<your-database-name>
DB_USERNAME=<your-database-username>
DB_PASSWORD=<your-database-password>
Next, you will run your migration using the following command:
php artisan migrate
Step 6: Create Controller and Request
Create a resource Controller, run the following command:
php artisan make:controller PostController -r
Resource controllers make it painless to build RESTful controllers around resources.
This is the initial content of PostController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
Next, create a Request file, run the following command:
php artisan make:request PostStoreRequest
As many of you already know, there are many ways to validate request in Laravel. Handling request validation is a very crucial part of any application. Laravel has some outstanding feature which deals with this very well. This is the initial content of PostStoreRequest.php:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class PostStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
HTTP Status Codes
We’ve also added the response()->json()
call to our endpoints. This lets us explicitly return JSON data and send an HTTP code the client can parse. The most common codes you’ll be returning will be:
- 200 : OK. The standard success code and default option.
- 201 : Created. Object created. Useful for the store actions.
- 204 : No Content. When the action was executed successfully, but there is no content to return.
- 206 : Partial Content. Useful when you have to return a paginated list of resources.
- 400 : Bad Request. The standard option for requests that cannot pass validation.
- 401 : Unauthorized. The user needs to be authenticated.
- 403 : Forbidden. The user is authenticated but does not have the permissions to perform an action.
- 404 : Not Found. Laravel will return automatically when the resource is not found.
- 500 : Internal Server Error. Ideally, you will not be explicitly returning this, but if something unexpected breaks, this is what your user is going to receive.
- 503 : Service Unavailable. Pretty self-explanatory, but also another code that is not going to be returned explicitly by the application.
Step 7: Setup CRUD (Create, Read, Update and Delete)
1. Setup Routes
Note: All API requests will need the header Accept: application/json
.
Add the routes to the API routes file, to access all the functions we wrote.
Now, open routes/api.php and update the following code into that file:
Route::get('posts', "[email protected]"); // List Posts
Route::post('posts', "[email protected]"); // Create Post
Route::get('posts/{id}', "[email protected]"); // Detail of Post
Route::put('posts/{id}', "[email protected]"); // Update Post
Route::delete('posts/{id}', "[email protected]"); // Delete Post
or you can add a resource route like this:
Route::resource('posts','PostController');
Now, open app\Http\Controllers\PostController.php and update the following code into that file:
2. Read All Post
For, get the list of all posts. Update the following code into that file:
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
// All Posts
$posts = Post::all();
// Return Json Response
return response()->json([
'posts' => $posts
],200);
}
Get the detail of the post by ID. Update the following code into that file:
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
// Post Detail
$post = Post::findOrFail($id);
if(!$post){
return response()->json([
'message'=>'Post Not Found.'
],404);
}
// Return Json Response
return response()->json([
'post' => $post
],200);
}
3. Create Post
Now, open app\Http\Requests\PostStoreRequest.php and update the following code into that file:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class PostStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
if(request()->isMethod('post')) {
return [
'name' => 'required|string|max:258',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'description' => 'required|string'
];
} else {
return [
'name' => 'required|string|max:258',
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'description' => 'required|string'
];
}
}
/**
* Custom message for validation
*
* @return array
*/
public function messages()
{
if(request()->isMethod('post')) {
return [
'name.required' => 'Name is required!',
'image.required' => 'Image is required!',
'description.required' => 'Descritpion is required!'
];
} else {
return [
'name.required' => 'Name is required!',
'description.required' => 'Descritpion is required!'
];
}
}
}
Now, open app\Http\Controllers\PostController.php and update the following code into that file:
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(PostStoreRequest $request)
{
try {
$imageName = Str::random(32).".".$request->image->getClientOriginalExtension();
// Create Post
Post::create([
'name' => $request->name,
'image' => $imageName,
'description' => $request->description
]);
// Save Image in Storage folder
Storage::disk('public')->put($imageName, file_get_contents($request->image));
// Return Json Response
return response()->json([
'message' => "Post successfully created."
],200);
} catch (\Exception $e) {
// Return Json Response
return response()->json([
'message' => "Something went really wrong!"
],500);
}
}
4. Update Post
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(PostStoreRequest $request, $id)
{
try {
// Find Post
$post = Post::findOrFail($id);
if(!$post){
return response()->json([
'message'=>'Post Not Found.'
],404);
}
$post->name = $request->name;
$post->description = $request->description;
if($request->image) {
// Public storage
$storage = Storage::disk('public');
// Old iamge delete
if($storage->exists($post->image))
$storage->delete($post->image);
// Image name
$imageName = Str::random(32).".".$request->image->getClientOriginalExtension();
$post->image = $imageName;
// Image save in public folder
$storage->put($imageName, file_get_contents($request->image));
}
// Update Post
$post->save();
// Return Json Response
return response()->json([
'message' => "Post successfully updated."
],200);
} catch (\Exception $e) {
// Return Json Response
return response()->json([
'message' => "Something went really wrong!"
],500);
}
}
5. Delete Post
Delete post by ID. Update the following code into that file:
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
// Post Detail
$post = Post::findOrFail($id);
if(!$post){
return response()->json([
'message'=>'Post Not Found.'
],404);
}
// Public storage
$storage = Storage::disk('public');
// Iamge delete
if($storage->exists($post->image))
$storage->delete($post->image);
// Delete Post
$post->delete();
// Return Json Response
return response()->json([
'message' => "Post successfully deleted."
],200);
}
You may or may not be aware that there is an artisan command to create the symbolic link from the storage folder to the public folder.
What it does is, it allows us to access the files. By default, laravel wants you to store your files in the storage directory keeping the public directory clean only for your public files.
This command helps us to generate symbolic links.
php artisan storage:link
It’d be a good idea to follow along with the simple demo app that can be found in this GitHub repo.
Thank you for reading this article!!
Read Also: Laravel Livewire Crud Tutorial
If you have any queries or doubts about this topic please feel free to contact us. We will try to reach you.
programming
via Laravel News Links https://ift.tt/2dvygAJ
February 12, 2021 at 09:45AM