[UPDATED] Building RESTful APIs with Lumen and OAuth2

If you are thinking about building fast RESTful APIs in a quick and simple way, then, Lumen is here!.

Omar Elgabry
OmarElgabry's Blog
12 min readOct 11, 2016

--

Lumen API OAuth2

Lumen eliminates all the unnecessary and heavy features in Laravel and load only components like Eloquent, middleware, authentication & authorization, …etc which keeps it light and fast. Lumen focuses on building Stateless APIs​. Therefore, sessions and views are no longer included in the latest version of Lumen.​​​

Index

  • What Do We Mean by RESTful APIs?
  • Why Using Lumen in Creating RESTful APIs?
  • What We Are Building?
  • Setting the Development Environment
  • Creating the Models and Their Relationships
  • Creating Migrations
  • Inserting Fake Data
  • Creating the Routes & Controllers
  • Implementing the Controllers
  • Using OAuth2​ Server​
  • Conclusion

What Do We Mean by RESTful APIs?

First and foremost, What do we mean by building RESTful APIs?. You may have heard the term RESTful, but, don’t know what does it actually mean. So, it worth to know now before moving further.

REST is an architectural style for building APIs. It stands for “Representational State Transfer”. It means when we build an API, we build it in a way that HTTP methods and URIs mean something, and the API has to respond in a way that’s expected.

Why Using Lumen in Creating Restful APIs?

In short, It’s fast, light, and easy!

One Of the Fastest Micro-frameworks

Although all the candidates; Laravel, Slim, & Lumen are faster than you will ever need. With Lumen, your API will support from ~1200–1700 requests(if not more depending on your machine) in a range of 10 seconds with 10 simultaneous requests. It’s great speed makes it a perfect candidate for building a RESTful API.

The following command will instruct Apache Benchmark to run for 10 seconds with 10 concurrent requests.

Use Laravel Features, While Remaining Light

When working on RESTful APIs, you won’t need all the features in a full stack framework. Lumen has the best features of Laravel in a light version, while remaining expressive, intuitive, and simple. Lumen removes all the parts that you probably won’t need.

Easier Than You Might Think

It’s easy to configure, understand, and upgrade. Since Lumen is powered by Laravel’s components, you can easily upgrade your Lumen application to the full Laravel framework.

What We Are Building?

We are going to build a simple application, indented for small projects, helps to understand creating RESTful APIs with Lumen and OAuth2, know how to authenticate and authorize, and more.

The RESTful API is for Posts and Comments, where Users can view, create, update, and delete. It provides authorization mechanism to authorize against access tokens using OAuth2.

You can find the final RESTful API on GitHub. You will need to check the GitHub repository as you are following along throughout this tutorial.

Although this tutorial focuses on building an API for Posts and Comments(just for demonstration purposes), however, you can follow the same steps to build an API for whatever you want.

Setting the Development Environment

Installing Lumen via Composer Create-Project

Lumen utilizes Composer to manage its dependencies.

Laravel Homestead

Laravel Homestead is an official, pre-packaged Vagrant box that provides you a wonderful development environment without requiring you to install PHP, HHVM, a web server, and any other server software on your local machine. Source

If you want to take the advantage of using Laravel Homestead, then follow the Installation Guide.

WAMP, LAMP, MAMP, XAMP Server

If you are using any of WAMP, LAMP, MAMP, XAMP Servers, then then don’t forget to create a database, probably a MySQL database.

Configure the .env File

Make a copy of the .env.example file, and rename it to .env. Then, set your application key to a random string with 32 characters long, edit database name, database username, and database password if needed.

If you are receiving Class ‘Memcached’ not found error, edit the .env file and change the following:

CACHE_DRIVER=array
QUEUE_DRIVER=array

Thanks to Ozal MEHMETi.

Configure the Bootstrap File

Go to bootstrap/app.php file, and uncomment $app->withEloquent(); and $app->withFacades();

Creating the Models and Their Relationships

Eloquent is the ORM of Lumen, which allows you to interact easily with the database. Eloquent Models allow you to query & insert data in your tables. Eloquent models extend Illuminate\Database\Eloquent\Model class.

We have three Models; User, Post, & Comment. So, let’s create them.

Defining Models

User

By default, the User Model comes with Lumen when installed Via Composer Create-Project, you just need to add Hash facade and edit the fillable & hidden attributes

Post

Comment

Defining Relationships

Since Database tables are often related to each another, Eloquent makes it easy to work with these database tables relationships by defining relationships between model classes. For example, a post may have one or more comments, and every comment is related to a single post(One To Many).

Post

Comment

Creating Migrations

Migrations allow you to easily build, modify and share the application’s database schema. We will create three tables; users, posts, & comments.

Creating Migration Files

To create a migration file, use the make:migration Artisan command.

These commands will create migration files in your database/migrations folder.

Migration Structure

In each migration file, specifically, inside “up()” method, we can create a new table and define it’s columns.

Users

Every user has a unique, auto-incremented id, a name, an email, and a password.

Posts

A post has a an id, title, content, and a foreign key points to the user who created that post.

Whenever we delete or update a user, the database will cascade down affecting the referencing rows. This is used to force referential integrity at the database level.

Comments

It’s same idea as in posts table, where every comment has a content, and a foreign key points to the user who created that comment, and another foreign key points to the post related to that comment.

It doesn’t go without saying, If you deleted a user or a post, the database would cascade down deleting all the referencing comments.

Timestamps

By default, $timestamps property of the Eloquent model is set to true. So, Eloquent expects created_at and updated_atcolumns to exist on our tables. “$table->nullableTimestamps()” will create created_at and updated_at columns automatically.

Running Migrations

Finally, It’s time to apply what we’ve defined so far. To run all migrations, use the migrate Artisan command.

After running this command, your database should have three tables, with their columns defined in the migration files.

Inserting Fake Data

Factories are useful to create and insert fake data for our Eloquent models classes, while the Seeder execute these factories. In fact both of them can insert data into the database.

We will use Faker library to generate fake data. It’s already installed with Lumen.

Model Factories

To keep the database in a consistent state. A foreign key must have values that exist in the primary key it’s referring to. For example user_id column in posts table must have values from 1 to 10(assuming we inserted 10 or more Users).

Seeding the Database

A seeder class contains only one method by default; “run()”. This method is called when we run seeders. Seeders use model factories to generate & insert database records.

Don’t forget to include User, Post, and Comment classes so you can use them.

Running Seeders

Now, we are going to seed the database with fake data.

Creating the Routes & Controllers

Routes link URIs to controller’s action method, while Controllers handle the request and make a response.

Routes

All the routes are defined in the routes/web.php file.

Controllers

In this tutorial, we will create 4 controllers; UserController, PostController, CommentController, & PostCommentController. All controllers must extend the base controller class.

The final code for controllers won’t be included here as they are already available in the GitHub repository.

Implementing the Controllers

The API will be used to create, read, update, or delete data, right? So, we need to write the code that will take care of these operations.

Inside each controller, we will define action methods to create, read, update, and delete data. Here is an example of the UserController class.

Again, the final code for controllers won’t be included here as they are already available in the GitHub repository.

Validating User Inputs

Whenever the client wants to store or update an existing User, the client needs to submit an email and a password. Of course, there are some validations we need to run against user inputs.

For example, we need to make sure the email field exists in the first place, and it’s a valid email, and also it has to be unique. All of these validations can be easily done with Lumen using “$this->validate()” method. It returns a JSON response with the relevant error messages if validation fails.

Don’t Repeat Yourself (DRY)

If you notice, there are some code snippets we have been using over and over again. For example, sending a JSON response with success and error message. So, it’s better the keep these snippets in the base controller class.

Using OAuth2 Server

The most important part of this tutorial is how to install and use OAuth2​ Server. This package adds authorization layer to your application by using access tokens.

About OAuth2 and How It Works

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service.Source

Before diving deeper into this package, you need to have a good knowledge of the principles behind the OAuth2 specification.

If you need a refresher, or you want to learn about OAuth2, DigitalOcean has a good Introduction to OAuth 2.

Installing the OAuth2 Server

  1. Add “lucadegasperi/oauth2-server-laravel”: “^5.2” to ‘require’ in composer.json file.
  2. Run composer update to update and install(if not already installed) all the dependencies.
  3. Copy configuration folder vendor\lucadegasperi\oauth2-server-laravel\config into lumen-api-oauth folder.
  4. Copy all migration files in vendor\lucadegasperi\oauth2-server-laravel\database into database\migrations.
  5. Register service providers and middlewares

Configuring the OAuth2 Server

  1. Create a seeder class for OAuth called OAuthClientSeeder for example. This class will generate and insert data tooauth_clients table.

2. Make a call to OAuthClientSeeder in the DatabaseSeeder class.

3. Run composer dumpautoload to update the autoloader because of the new classes we’ve added recently.

4. Run Migrations and Seeders

5. Define a route to respond to the incoming access token requests.

6. Choose and Enable the grant type suitable for us. In this tutorial, we will use Password Grant.

This grant needs the client to send the resource owner(user) email and password along with client id and client secret. So, we need to define a method where you check if the provided user is a valid one.

So, we will create a verify($email, $password) method in the User class.

Testing the OAuth2 Server

You can test the API using Postman, and make a POST request to: http://lumenapi.com/oauth/access_token.

In case of using any of WAMP, LAMP, MAMP, XAMP servers, make a POST request to http://localhost/lumen-api-oauth/public/oauth/access_token.

The client needs to submit 5 fields: username, password, client_id, client_secret, and grant_type.

The username field is the email in Users table.
The password field is secret.
The client_id field is the id in oauth_clients table.
The client_secret field is the secret in oauth_clients table.
The grant_type field is password.

The authorization server will then issue access tokens to the client after successfully authenticating the client credentials and presenting authorization grant(user credentials).

Protecting the Resources Using Access Tokens

After obtaining an access token, we need to restrict the access to controller action methods. Therefore, clients need to present the access token to get access to the resources.

For example, In the PostController class, we can assign oauth middleware to all methods which need authorization via access token except index & show methods. So, if the client needs to remove a post, the client must send a valid access token.

Now, you can assign oauth middleware to action methods in UserController & PostCommentController classes.

If you still receive invalid request error even if access token is sent, then, key and value pairs should be sent using www-url-encode instead of form-params.

The Current Authorized User Id

You might be asking How to get the id of the authorized user?. Every access token is related to a user, if you remember, we sent the user email and password to get an access token.

So, after the oauth middleware validates the access token sent by the client, you can access the authorized user id by calling:

And because we are going to get the authorized user id multiple times, it’s better to keep this line of code in the base controller class.

I See authorize Middleware, What Is This?!

If you have seen the following line of code in any Controller constructor in the GitHub repository, just uncomment it, Why? Because In this tutorial, we didn’t cover how to authorize against ownership, and non-admin Vs admin users.

Conclusion

Building a RESTful API couldn’t be easier with Lumen, even if you aren’t familiar with Laravel. Now, you should be able to install, configure, and build your own RESTful API with OAuth2. You can take what we have done further and tailor it according to your needs.

--

--

Omar Elgabry
OmarElgabry's Blog

Software Engineer. Going to the moon 🌑. When I die, turn my blog into a story. @https://www.linkedin.com/in/omarelgabry