Laravel API Series: Controllers, CRUD, Routing and Search Functionality
Tags: laravel, webdev, beginners, tutorial
Published: 2022-04-07 03:43:28

## 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:
```sh
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
<?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:

```php
     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:
```php
    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:
```php
    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:
```php
    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:
```php
    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:
```php
use App\Http\Controllers\PostController;
```
### Creating routes
To create a post, you need to connect the `store` function to a route like so:
```php
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:
```json
{
    "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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w8fup5naybkqesrtj8mk.png)
- 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:
```php
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3l7r5sthq7q0xvvkfoz.png)
- 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: 
```php
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fthmryc9zsgcc8z5jtu4.png)
- 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:
```php
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:
```json
{
    "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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82llbx54vw639w322s0d.png)
- 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:

```php
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k40peyg63zukvr24j2cy.png)
-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:
```php
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:
```php
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:
```php
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ri266bu29f04tp7u5i69.png)

- 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
<?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:
```php
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!