Laravel API Series: Controllers, CRUD, Routing and Search Functionality

Laravel API Series: Controllers, CRUD, Routing and Search Functionality

What you'll learn

In this part of the series, you'll learn about the following:

  • What controllers are, and how to create and use them in Laravel
  • Implementing CRUD functionalities
  • Routing in Laravel
  • Implementing search functionality

Controllers

A controller in Laravel is a class that is used to organize logic in your application. For example, all the logic related to your Post model will be inside the PostController, these include, but not limited to functionalities like, creating, updating, reading, deleting, and searching post data from the database.

Creating controllers and CRUD functionalities

The easiest way to create a controller in Laravel is by running the following command:

php artisan make:controller PostController --resource

The above command will create a PostController file inside /app/Http/Controllers folder, the --resource flag will generate common resource methods inside the controller file, so the generated file contents will look like so:

<?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)
    {
        //
    }
}

In this file you have the dependencies and boilerplate of all the functions you need to create, read, update and delete data from the post table (again, Artisan to the rescue!), but since I'm building an API, I will remove some of them so I'll have the following functions:

  • store - for creating a post
  • index - for fetching all data from the posts table
  • show - for fetching a single post
  • update - for updating a post
  • destroy - for deleting a post

Now that Laravel has scaffolded those functions, all you need to do is to define them anyhow you like.

Create a post (store) function

The store function as the name suggests, will be responsible for storing a post to the database. Thanks to Laravel's simplicity, you can add a resource with a single line like so:

     public function store(Request $request)
    {
        return Post::create($request->all());
    }

The above code uses the create method on the Post model to add all the data that comes in through the request object to the database.

Fetch all posts (index) function

The index function will return all the posts in the database. For the PostController, your index function should look like so:

    public function index()
    {
        return Post::all();
    }

The above code uses the all method on the Post model to fetch all the posts from the database.

Fetch a single post (show) function

The show function will return a single post from the database. For the PostController, your show function should look like so:

    public function show($id)
    {
       return Post::find($id);
    }

The above code uses the find method with the $id as parameter on the Post model to fetch the post with that particular id from the database.

Update a post (update) function

The update function will update a post in the database. For the PostController, your update function should look like so:

    public function update(Request $request, $id)
    {
        $post = Post::find($id);
        $post->update($request->all());
        return $post;
    }

The above code does the following:

  • Declares a $post variable with the result of the find method using the $id as a parameter. That will be the post with that particular $id in the database.
  • Use the update method to update with all the data passed to the request object as a parameter to update that particular post.
  • Returns the updated post.

Delete a post (destroy) function

The destroy function will delete a post from the database. For the PostController, your destroy function should look like so:

    public function destroy($id)
    {
        return Post::destroy($id);
    }

The above code uses the destroy method with the $id as parameter on the Post model to delete the post with that particular id from the database. Now that you've seen how to create controllers and define the create, read, update, and delete functions, Next, I'll show you how to connect those functions to routes(URLs) that the client will use to access data from the application.

Next, I'll show you how to work with routing in Laravel.

Routing

Routing in web development is the process of pointing a particular route in your application to the code or functionality that handles the request.

You've seen a bit of routing in Laravel when you wrote your first Route::get(... function in the first part, Now lets handle routing in our application. After all the store, index, update and destroy functions have been defined, now go to the api.php file inside /routes folder and add the following to the dependencies on top of the file:

use App\Http\Controllers\PostController;

Creating routes

To create a post, you need to connect the store function to a route like so:

Route::post('/posts', [PostController::class, 'store']);

The above route connects the store function to any POST request that goes to the localhost:8000/api/posts with the fields to create a post like so:

{
    "author_id": "1",
    "title": "How to use Laravel",
    "body": "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?",
    "likes": 0, 
    "draft": 0
}

store result

  • The purple box is the type of request you'll send for this route, which is a POST request.
  • The yellow box is the URL of the route localhost:8000/api/posts.
  • The red box is the data I sent to the server in JSON format (notice that I did not add the id, created_at and updated_at fields as those will be added automatically, you can omit the likes and draft columns too, and their default values will be populated inside the database).
  • The green box is the result you'll get after sending the request successfully - this will be the data that was created in the database (remember the function returns the created resource)

Fetch all posts

To fetch all the posts in the database, you need to connect the index function to a route like so:

Route::get('/posts', [PostController::class, 'index']);

The above route connects the index function to any GET request that goes to the localhost:8000/api/posts route, which will then return all the posts in the database like so: index result

  • The purple box is the type of request you'll send for this route which is a GET request.
  • The yellow box is the URL of the route (localhost:8000/api/posts).
  • The green box is the result you'll get after sending the request successfully - this will be all the posts in the database.

Fetch a single post

To fetch a single post, you need to connect the show function to a route like so:

Route::get('/posts/{id}', [PostController::class, 'show']);

The above route connects the show function to any GET request that goes to the localhost:8000/api/posts/1 which will then return the post with the id of 1 or any number you add to the end of the URL like so: find result screenshot

  • The purple box is the type of request you'll send for this route, which is a GET request.
  • The yellow box is the URL of the route localhost:8000/api/posts/1.
  • The green box is the result you'll get after sending the request successfully - this will be the posts with id of 1 in the database.

Update a single post

To update a single post, you need to connect the update function to a route like so:

Route::put('/posts', [PostController::class, 'update']);

The above route connects the update function to any PUT request that goes to the localhost:8000/api/posts/3, with the fields you would like to update like so:

{
    "author_id": "1",
    "title": "How to use Laravel",
    "body": "post updateds",
    "likes": 0, 
    "draft": 0
}

Which will then return the updated post like so:

update result

  • The purple box is the type of request you'll send for this route, which is a PUT request.
  • The yellow box is the URL of the route localhost:8000/api/posts/3.
  • The red box is the data sent alongside the request.
  • The green box is the result of the request, which is the post that was updated.

Note: You can omit some fields. For example: you can update only the post title and leave the rest as they are.

Delete a post

To delete a single post, you need to connect the destroy function to a route like so:

Route::delete('/posts/{id}', [PostController::class, 'destroy']);

The above route connects the destroy function to any DELETE request that goes to the localhost:8000/api/posts/1 which will then return the id of the deleted post like so: delete result screenshot -The purple box is the type of request you'll send for this route, which is a DELETE request

  • The yellow box is the URL of the route localhost:8000/api/posts/1.
  • The green box is the result of the request, which is the id of the post that was deleted.

Using resource routes

Because Laravel is all about simplicity and developer experience, you can connect all the routes above to the controller using a single line of code, like so:

Route::resource('posts', PostController::class);

And all the routes should work as they did before, go ahead and test them!

Note: The resource method only contains the store, index, show and destroy routes, so you need to define a route for any other function you have in the controller.

Next, we'll look at how to implement basic search functionality.

Search Functionality

After adding the create, read, update, and delete functions, I want to add a search function to the post controller method, so I can search for posts by title. So you need to add the search function inside the controller like so:

public function search($title)
  {
  return  Post::where('title', 'like', '%' . $title . '%')->get();
  }

The above code uses the where method with the $title parameter on the Post model to fetch all the posts with title that matches the $title string from the database.

Connect Search route

To search for posts, you need to connect the search function to a route like so:

Route::get('/posts/search/{title}', [PostController::class, 'search']);

The above route connects the search function to any GET request that goes to the localhost:8000/api/posts/search/{title} which will then return all the posts with title that matches the {title} string from the database, like so:

search endpoint result

  • The purple box is the type of request you'll send for this route; GET
  • The yellow box is the URL of the route localhost:8000/api/posts/search/react.
  • The green box is the result of the request, which is the only post that has react in its title.

Next, I'll show you how to setup the same CRUD and Search functionalities for AuthController.

Setup CRUD and Search for AuthorController

The AuthorController file will be very similar to the PostController, I would advise you to try to implement the functionalities of this file before reading on. Lets get to it now, add this to your AuthorController file like so:

<?php

namespace App\Http\Controllers;

use App\Models\Author;
use Illuminate\Http\Request;

class AuthorController extends Controller
{
       /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return Author::all();
    }



    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        return Author::create($request->all());
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
       return Author::find($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)
    {
        $author = Author::find($id);
        $author->update($request->all());
        return $author;
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        return Author::destroy($id);
    }

        /**
     * Search the storage with a given text.
     *
     * @param  int  $name
     * @return \Illuminate\Http\Response
     */
    public function search($name)
    {
return  Author::where('name', 'like', '%' . $name . '%')->get();
    } 
}

The above defined the same functionalities as PostController but for Author model, you can also define the routes the same way like so:

Route::resource('authors', AuthorController::class);
Route::get('/authors/search/{name}', [AuthorController::class, 'search']);

And that's it!, you can now create, read, update, delete, and search authors in your application! Go ahead and test it out.

Recap

In this part of the series, you learned about and how to do the following:

  • Create controllers using artisan.
  • Generate resource controllers.
  • Create the CRUD (create, read, update, delete, and search) functionality
  • Connect routes to controller functions.
  • Group routes with the resource() method.
  • Add a basic search functionality.

In the next part, you'll learn more about Table Relationships by connecting the post table to the authors table, Validation by validating request fields, and also set up Laravel Sanctum for the API Authentication.

Please use the comment section for suggestions and feedback, I would really appreciate that. I hope you enjoyed the article!