Series: Build an app with Laravel5 (backend) and Angularjs (frontend) – Part 1

Laravel & Angularjs works really well together, if used in a correct way. In this Laravel & Angularjs Series, we will be creating an app where Laravel will be used for creating an API and Angularjs for consuming that API.

This series is aimed at those, who want to completely separate their frontend and backend. This is the most common use case in hybrid app development using phonegap or ionic framework.

So without further due, let’s get started with the Laravel Part.

Install Laravel & Create New Project

First Install Composer By Following this guide.

Then, download the Laravel installer using Composer.

Once successfully installed, you can type laravel new command to create new Laravel project.

After successfully creating the project, make sure your webserver is running (you can use XAMPP, LAMP, MAMP), now go into the project directory and type.

Now you can open the following url.


And you will see the Laravel front page.

Now we will add a package called Laravel-5-Generators. This Laravel package provides a variety of generators to speed up your development process.

You can install the generator via composer as:

Now open the app/Providers/AppServiceProvider.php file and updated the register function as,

Now run,

You will see new commands added in the make:* section.

Setup DB, Create Migration & Insert Dummy Data

Setup DB

First, rename the .env.example file in the laravel installation root directory to .env

now open the .env file and change the following:-

DB_DATABASE= your_database_name
DB_USERNAME= your_database_username
DB_PASSWORD= your_database_password

Create Migration

Next step is to create the migration, as the laravel documentation says, Migrations are like version control for your database, allowing a team to easily modify and share the application’s database schema. Open the terminal and type the following command to create the migration.

You can see the created migration in database/migrations folder. Open the migration file and replace it with this code.

Here you can see we have added the id, joke, user_id and timestamps fields. Where id is auto incrementing, joke is the body of the joke and user_id will be used for the user who will submit the joke. Here there are two functions one is up and other is down. The down function is the exact opposite of the up and will be used if we want to revert back the migration.

Now run the following command.

Now have a look at the database, you can see the new jokes table there. Along with jokes table, laravel creates three other tables namely users, migrations, password_resets.

Now to demonstrate the down function. Let’s say we want to change the joke field with body. What you can do is, change the field in the migration table.

Now run the following commands.

Now open the database and check the structure and you can see the jokes table joke field renamed to body.

Insert Dummy Data

The next step is to insert the dummy data that we can use throughout the  development process. For inserting dummy data we will use a package called fzaninotto/faker.

First we need to install this package,

Now first create a Joke Model by typing:

Now create the seed file which will be used to insert dummy data.

You can see the created seeder file in database/seed folder. Open JokesTableSeeder.php and add the following.

At the top you can see, we have added App\Joke that makes us available the jokes model and we are using to create new jokes as Joke::create. Here you can see we have used $faker object, it is availabe through package. For the list of all the available functions, you can have a look at their documentation.

Now Create the new seed file for users table as.

Now open UsersTableSeeder.php and add the following.

Here you can see we have added App\User at the top, which means we are requiring user model. It is availabe through default laravel install.

The next step is to open DatabaseSeeder.php and add the created seeder classes.

Now before using the seed command we need to do one more thing. Open the Joke Model file. This will be inside app root folder and add the fillable array inside the class as.

By using this we can mass insert values in the database table.

Now the last step is to run the db seed command as.

After that you can see the database table with all the dummy entries.

Creating & Testing Routes

In the last section we successfully created the database, created migration and prepared seeder classes. In this section we will create our routes or api end points which we can hit to get data.

Open the routes.php file and add the follwing code:

Now we need to create the JokesController, for this we will use generators like,

This command will create the jokescontroller with all the required methods.

Now run this command:

You will see output similar to this:

Now we can add the prefix to all these routes as, in the routes.php updates the code as:

Now your output will look like:


Now open the JokesController.php, add the following at the top,

Now update the index method as:

Here we are using the Eloquent ORM, which makes it easy to work with database. If you don’t know about eloquent, have a look at the Eloquent Documentation.

The Joke::all() will return all the rows from the jokes table.

Now run the server as:

and open:

You will see all the records from the jokes table, also it is worth mentioning, the data is casted to json automatically.


Now using the browser is good if you want to test GET request, but if you want to test POST, PUT, PATCH, DELETE request we probably will not use browser for this. So, for that scenario we can use Curl, which is perfectly fine or we can use a utility called POSTMAN which is a chrome extension. That makes it really easy to test all the requests. Let’s see how we can test our api with postman. Install the postman extension and open postman:


Here select the request (GET, POST etc.), enter url and press send, the output is similar to the one we saw in browser but this will prove more useful once we get to other requests.

Now, yes it is a working api but there are some problems with it:

  • It is not a good idea to return all the results at once.
  • We are showing the exact structure of the table.
  • We are sending any error message and response codes.

Now in the following sections, we will work on improving that api.

Responses & Codes

Now let’s add the status codes to the data, the available status codes are:


Updated the index method in the JokesController.php as follows:

Now open the /api/v1/jokes url in the postman, you can see status returned as 400.


The 400 is mainly for the bad request, so the status that we probably want to return is 200, so change the code as follows:

Now again hit the endpoint/url in the postman, you can see status returned as 200.

Now let’s implement the route for getting single joke, we can see from php artisan route:list, when we get to api/v1/jokes/{jokes} we are calling the show method and will get single joke.

So update the show method as follows:

Now try accessing this route, if the joke with specific id not exists we will get the error response and if it exists we will get the 200 response.

If the joke exists:


If the joke doesn’t exists:



Transforming Data

At that point, we can see that, we are returning the exact db table structure, and it is not a good idea, it may be possible we only want to show specific fields and don’t want to show the fields name as in the table. So for this we can transform the data before displaying.

Add the following two methods at the bottom of the JokesController Class in the JokesController.php,

Now update the index and show methods as:

Now again hit the routes and you will see the transformed data.

Eloquent Relationships

Using Eloquent Relationships we can relate two tables.

First we need to define the relationship between the two tables users and jokes and then we can join the tables data.

Let’s start by adding a relationship:

open the User.php model file and add the following method:

and open the Joke.php model file and ad the following method:

Now open the JokesController.php and update the show method as follows, before that add the following code at the top:

Now update the show method as:

and our updated transform method with look like this:

So, our updated show method code will look like this, here first we are joining User table data with the jokes tables, also we are finding the previous and next joke and then we are adding them to the response. So our response will now look like this:


Where submitted_by data is coming from users table after joining.

Implement POST, PUT, DELETE requests

Open JokesController.php and update the store, update and destroy methods as follows:

First add the following code at the top of the file,

Now update the following methods:

To test POST request, open postman and send post request as follows:


Similarly, you can test Update and Delete requests.


For pagination, Laravel provides a very simple method called paginate(), let’s see how we can implement pagination. Open JokesController.php and update the index method as follows:

Now access the route, you will see error something like this,


The problem is now we need to update the transformcollection method in the JokesController.php as:

Now go to the route you will see the paginated result, like this.


Currently, we are hard coding the pagination to 5 elements but we can use query string to specify the no. of elements. The updated index method will look like this:

Here we are checking to see, if the limit is present as query string, if yes use that value otherwise the no. of elements are default to 5.

Implementing Search

Now let’s implement the search functionality, update the index method as follows:

Now you can test the search as follows:


Adding JWT Auth

Now we will add the security to the routes, such that only the authenticated users can request the data, otherwise they will get error.

Let’s start with basic auth, that laravel provides by default, open the JokesController.php and add the contructor function as:

This means we are using basic auth on all routes. When we now try to view the route in the browser, we will first need to signin and then we see the data like.


Now, if we type the correct credentials, only then we can see the data.

But we won’t be using this for our api, for api’s it is better to use token based authentication, which means whenever the user authenticates he will be provided with the token, and the user will then send this token with each request and if the token is valid, only then the data will be displayed.

For Token Based Auth, we will use a laravel package called jwt-auth ,

First open the composer.json and add the following item to the required array,

Now run the following command:

It will download the jwt-auth package.

Now Open config/app.php file and add the following item to the providers array:

Also in the config/app.php, add the following items to the aliases array:

Now publish this package from command line as:

Now you will see a new file in the config folder called jwt.php, Now we need to generate jwt specific key from command line as:

Now you can see the key in the secret field changed to new key.

Now open the routes.php and add the following routes:

Add the following middleware to the construct method in the JokesController.php:


Now we need to make the AuthenticateController from the command line as:

Now open the AuthenticateController.php and update the file as follows:

Now try to hit the route, /api/v1/jokes, you will get an error token not provided like this:


Which means, we first need to generate token that we can generate by sending post request to api/v1/authenticate with email and password as following:


Now you can send the requests with this token and then you will get the result as expected.


Tackling CORS

Now our api is working fine, but there is last thing to take care of, now let’s say if we put this api online, no one will be able to access the api due to cross domain restrictions. So to overcome this we can install a Laravel package called laravel-cors.

First install the package using composer:

Now add this package to config/app.php file’s providers array as:

Now to use this package, open the routes  file and update the routes as follows:

Wrapping Up Part 1

Hopefully this tutorial was helpful and you have created your first API by the end of it.

Feel free to leave any feedback or questions in the comments below and let me know if there’s anything you need help with or if I can clarify anything.

Thanks @jeffrey_way (laracasts) for his awesome screencasts, learned lot from him & jwt-auth inspiration by @ryanchenkie.

See Part 2 of this series, where we will create an app with AngularJS using this API.


Please Consider Donating (Click Here)

  • Кирилл

    You can use:
    $limit = $request->input(‘limit’, 5);
    insted of:
    $limit = $request->input(‘limit’)?$request->input(‘limit’):5;

    • Thanks @disqus_HGgfrOjw64:disqus for the neat trick.

  • Nasrul Hazim Mohamad

    Nice. neat and clean tutorial. love this!

    • Thanks Nasrul

      • Nasrul Hazim Mohamad

        just a note, in case anyone having problem with CSRF, here is the solution –

        in Http/Middleware/VerifyCsrfToken.php you have an array called $except. Just add your api uri.

        protected $except = [

        • Emil Reña Enriquez

          but I think there should be extra security enforcements to avoid spammers

          • @emilreaenriquez:disqus Like What?

          • Emil Reña Enriquez

            hmm actually I don’t know I’m new to laravel. but i have encountered a lot of spamming issues especially when dealing with api, once user is authenticated, and have the token he can spam POST data anytime, IG is doing great in handling and limiting these requests. do you have any suggestions? @mbaljeetsingh:disqus

  • Well Written! Waiting for your part 2!

  • tom

    Any idea when part two will be available?

  • Tobias Bruns

    When i run
    >php artisan make:seed JokesTableSeeder

    the seed file is named “JokesTableSeederTableSeeder.php”

    I assume, that i just have to type
    >php artisan make:seed Jokes


    Anyway, i tried both commands an when i run
    >php artisan migrate –seed

    i got the following exception:

    Class JokesTableSeeder does not exist

    Did i miss something?

    • Yes @Tobias you are right, thanks for spotting the error, it should be
      >php artisan make:seed Jokes
      and i have updated the post. Thanks.

      • Tobias Bruns

        OK. And do you have any idea why get the following exception:

        Class JokesTableSeeder does not exist

        when i run this command:

        php artisan migrate –seed

        I followed you’re tutorial and double checked everything but at this point, i stuck.

  • pradeep prasanna rajapaksha

    Great work bro.
    I just followed jwt auth and It works for me. 😀

  • Claudio González

    Maybe you forgot add this lines in App/Http/kernel.php:

    ‘jwt.auth’ => TymonJWTAuthMiddlewareGetUserFromToken::class,
    ‘jwt.refresh’ => TymonJWTAuthMiddlewareRefreshToken::class

    into the $routeMiddleware array.

    anyway thanks for your fantastic work

  • jacksinn

    Thanks for this! It reminded me of a Laravel 5/Angular tutorial I had seen earlier in the year but your article is much more thorough and very timely for my application.

  • xarp

    Nice tutorial. I have a question though – you are sending the “token” param in the url, but according to JWTAuth wiki ( it should be possible also using Header Authorization. However this gives me a “Token not provided” error. Did you try to test the Headers as well? I think it would be a more secure way to send the token.

  • Emil Reña Enriquez

    Great tutorial! a big thumbs up for @mbaljeetsingh:disqus! there are some codes and steps missing though but overall great job!

  • Basanta Dhakal

    As you said i have updated the code of index method to use the pagination as below it says method paginate doesnot exists :
    public function index(){
    $jokes = Joke::with(
    )->select(‘id’, ‘body’, ‘user_id’)->paginate(5);
    return Response::json($this->transformCollection($jokes), 200);
    When i am trying to test the post request in the postman it gives an error like:
    Whoops, looks like something went wrong.
    1/1TokenMismatchException in VerifyCsrfToken.php line 53:

    • I think you should use get request instead of post to see the paginated results.

    • Jonatan Santos

      edit AppHttpMiddlewareVerifyCsrfToken and add:

      protected $except = [

      • Jim Barrett

        This worked for me! Thanks!

  • Jimit

    Thanks @BljeetSingh for this Tutorial! Really helps to me. Thumbs Up!

  • nokah vandenhoven

    when i use this script “php artisan migrate –seed” then i got this error ( [ReflectionException] Class DatabaseSeeder does not exist )

    • Alex H

      Running “composer dump-autoload” before “php artisan migrate –seed” worked for me.

  • Alex H

    If you get a “Class jwt.auth does not exist” message after adding web token authentication, it’s because you need to edit the AppHttpkernel.php file. Specifically, you need to add the following two classes to the $routeMiddleware array:
    ‘jwt.auth’ => TymonJWTAuthMiddlewareGetUserFromToken::class,
    ‘jwt.refresh’ => TymonJWTAuthMiddlewareRefreshToken::class

    • Thanks, it worked !

    • lomelisan

      Well done bro @ASchopenhaur:disqus

    • foysal

      Everyone should implement this Code.

  • If you get installation failed when installing CORS, manually insert in composer.json and run composer update

  • Navdeep Singh

    Baljeet Singh ji..which chrome plugin is used while testing?

  • Ares


    I am getting a problem with the routs… I have:
    // API routes…
    Route::group([‘prefix’ => ‘api/v1’], function(){
    Route::resource(‘jokes’, ‘JokesController’);
    Route::resource(‘authenticate’, ‘AuthenticateController’, [‘only’ => [‘index’]]);
    Route::post(‘authenticate’, ‘AuthenticateController@authenticate’);
    Route::get(‘authenticate/user’, ‘AuthenticateController@getAuthenticatedUser’);

    and when I try to go to authenticate to post and get my token it returns a route error:

    Sorry, the page you are looking for could not be found.
    1/1 NotFoundHttpException in RouteCollection.php line 161

    Any idea on how to solve this? 🙁

    UPDATE: I used
    php artisan clear-compiled then
    php artisan route:cache to clear and recache routes… still nothing

    L.E: I restarted the server (php artisan serve…) and it works fine now… 🙂

  • Ares

    composer require barryvdh/laravel-cors 0.7.x does not work anymore. try:
    composer require barryvdh/laravel-cors dev-master

  • ricky spires

    Hello. I can not get the routing to work.
    Sorry, the page you are looking for could not be found.
    1/1 NotFoundHttpException in RouteCollection.php line 161

    —— dont worry. it was a dodgy install. works now 🙂

  • ricky spires

    There is an issue here…… works…

    {“previous_joke_id”:null,”next_joke_id”:2,”data”:{“joke_id”:1,”joke”:”Totam voluptate rerum alias minima ullam. Nesciunt quis blanditiis asperiores ut. Quos nesciunt esse qui.”,”submitted_by”:”Alexandrine09″}} does not work becuase there is no $id so it is not finding a [‘user’] and you get

    Undefined index: user

    • ricky spires


      • ricky spires

        here is a fix ….

        private function transform($joke){

        return [
        ‘joke_id’ => $joke[‘id’],
        ‘joke’ => $joke[‘body’],
        ‘submitted_by’ => $joke[‘user’][‘name’]
        return [
        ‘joke_id’ => $joke[‘id’],
        ‘joke’ => $joke[‘body’]


        but it would be nice to also pass the user name into the index view

        • ricky spires

          ok…. my bad.

          It does get fixed further along in the tutorial when it gets to pagination 🙂

          public function index(){

          $jokes = Joke::with(




          )->select(‘id’, ‘body’, ‘user_id’)->paginate(5);

          return Response::json($this->transformCollection($jokes), 200);


          • Drishti Saxena

            I face the same issue and it doesnt gets fixed even after pagination. In the error files of apache it says- [ssl:warn] [pid 4516:tid 576] AH01909: server certificate does NOT include an ID which matches the server name
            How do i fox this any idea?

    • Massimiliano Bertinetti

      use this in index

      public function index(){
      $jokes = Joke::all();
      foreach ($jokes as $joke) {
      $joke[‘user’][‘name’] = $joke->user->name;
      return response()->json([
      ‘data’ => $this->transformCollection($jokes)
      ], 200);

  • ricky spires

    POSTMAN – TokenMismatchException in VerifyCsrfToken.php line 67:

    Laravel 5.2


    • Make sure to comment the following line in /app/Http/Kernel.php


      • ricky spires


        Also noticed this further down for postman to work….

        protected $except = [

      • ricky spires

        Thanks 🙂

  • ricky spires

    Great tutorial 🙂

  • ricky spires

    Is it still good to use JWT Auth in Laravel 5.2 ???

  • Raghu Kumar

    How to refresh the token as it is expiring is 1 hour ???

  • olbap

    Is there any way to launch the REST service on an Apache server without “artisan serve”? thank you

  • biljka

    When I try to send post request to api/v1/authenticate with my email and password , I get this error everytime:
    “error”: “invalid_credentials”
    Because of this I can’t get my token, and move on. Anyone for help?

    • Have you commented that line in /app/Http/Kernel.php


      • biljka

        Yes, I have, but it’s still the same

      • Murad

        Can you guess what else can cause the same problem. I have also commented AppHttpMiddlewareVerifyCsrfToken::class, but getting the same error in postman:

        “error”: “invalid_credentials”

    • Roni Pinili

      If you are using the email and password generated by “Faker” use the password “secret” to any email.

    • Silas Selekane

      Hello, anyone with a solution for this error?

  • Dominic

    hi , thanks for the tutorial.. its works fine for me. I have a question. how can I make users register users if they are first time users from mobile app. should I hit the login route that is created if I run php artisan make:auth. this command creates some login and register and password reset routes. can you help

    • You shouldn’t make of make:auth (It wouldn’t work in a mobile app), What you need is the api endpoint for register, so you may have to create the new register route that accepts register info (possibly post request). When you send post request to that endpoint, register data should be saved to DB. And then you can login with that info. Hope, it’s helpful.

      • Dominic

        thank you so much..i tried the inbuild Route:auth. now I ll try the route register api.

  • Maen Emos

    Thank you for this brief and rich tutorial.
    The laravel validation is not working!! example:
    $this->validate($request, [
    ’email’ => ‘required|email|unique:users|max:100’,
    ‘password’ => ‘required|max:100’,

    when i put this validator into the controller I get an empty response!

  • bala choudry

    When i try to generate token i am getting {“error”:”invalid_credentials”}.

  • Carl Huxley

    Hi I’m struggling with the first post request using Postman. I get TokenMismatchException in VerifyCsrfToken.php line 53:
    If I comment out AppHttpMiddlewareVerifyCsrfToken::class, in Kernal.php I’m getting the error MassAssignmentException in Model.php line 424:

    I’m using laravel v5.1.36

    • greeter

      Solved this?I’m struggling with this too.

      • Ernesto Pérez

        Go to HTTP>Middleware>VerifyCsrfToken.php and in the $except array add: ‘api/*’
        Like this:
        protected $except = [

        • Manish

          Thanks @Ernesto Pérez . This solved my issue.

  • Luca

    Hi, Great tutorial; I’m a newbie
    I got an issue when I create the controller JokesController.

    I follow all the indications but when I try to see the route list there is only this:

    | Domain | Method | URI | Name | Action | Middleware |
    | | GET|HEAD | / | | Closure | web |

    where am I wrong?

  • Ahmad Yousef

    if you are getting this:
    “Maximum function nesting level of ‘100’ reached, aborting!”
    you can add this to the “bootstrap/autoload.php” : “ini_set(‘xdebug.max_nesting_level’, 200);”
    I learnt that from here: Thank you so much for this tutorial !

  • Jay Hughes

    Baljeet – Say you want to only show jokes that the user owns – do you have a good process for this? I’m using Auth::user() and then using that in the query – but it’s seems to be excessive since I’m having to do that on so many routes. Any advice?

  • solaire

    If you get this error:
    when executing php artisan migrate for the jokes table, try not copy the code with the copyfunction of the embedded code display thingy because it makes everything uppercase and that’s the problem

  • Hi,

    I got an error with this message

    MethodNotAllowedHttpException in RouteCollection.php line 218:

    No idea to solve this 🙁

  • Guaracy A. Lima

    Summarily would like to thank for the tutorial. In my implementation, JWT always returns the error ‘error’: ‘invalid_credentials’. Those credentials (email and password) should they be written to db using some encryption method?

  • Govind

    Thank you.. Great Tutorial

  • Burhan J

    Baljeet lovely tuto, really enjoyed doing it and had a good hands on while learning laravel… Keep up the good work.
    Just a small advice, please update the tuto with respect to the comments, so any new visitor(like me) dont have to face the issues already encountered (and solution provided) by fellow techies.

  • foysal

    how to know the users Password of Users table ?

    • Husam Aamer

      the password = ‘secret’
      see this code :

      ‘name’ => $faker->userName,
      ’email’ =>$faker->email,
      ‘password’ =>bcrypt(‘secret’)

  • Husam Aamer

    Thanks for this gorgeous tutorial , I’ve some corrections :

    – php artisan make:seed Jokes
    should be :
    – php artisan make:seed JokesTableSeeder

    This didn’t work for me :
    – Response::json
    this worked :
    – Response()->json

    While adding JWT auth you should do the following :

    In appHttpKernel.php
    ‘jwt.auth’ => TymonJWTAuthMiddlewareGetUserFromToken::class,
    ‘jwt.refresh’ => TymonJWTAuthMiddlewareRefreshToken::class,

    • Alexander Stefan

      With Laravel 5.4 I arrive only to “Implementing Search” without error (and some fix).
      when I implement “AuthenticateController”,
      http://localhost:8000/api/v1/authenticate WORK

      but (also if i set the token) to the page http://localhost:8000/api/v1/jokes/
      i do not receive “token not provided”, i receive:
      – (1/1) NotFoundHttpException
      – in RouteCollection.php (line 179)
      – at RouteCollection->match(object(Request))
      – in Router.php (line 548)

  • sumedha prithyani

    hello baljeet sir my postman get method is working but post method is not working for any api. When I use get method it properly give me correct response. But not for http://localhost:8000/api/v1/authenticate its post method. plz help me.

  • mohit99

    Hello Baljeet, I am getting an error, please help

    http://localhost:8000/api/v1/jokes/1 works fine


    here I am getting error:


    Undefined index: user

    I believe something is wrong in this part


    private function transformCollection($jokes){
    return array_map([$this, ‘transform’], $jokes->toArray());

    private function transform($joke){
    return [
    ‘joke_id’ => $joke[‘id’],
    ‘joke’ => $joke[‘body’],
    ‘submitted_by’ => $joke[‘user’][‘name’]