Monday , November 29 2021

Build REST API using Laravel Lumen for your Application – Android Coding by DMTechnolab

Hello guys today we will Build REST API Using a Micro php Framework to Lumon by Larva. We have already covered the basics of REST architecture in our previous posts. So in this post we will not talk about the basics of REST API and we will start building REST API directly. And after creating REST API we will create app in android platform.

So without wasting time Build our REST API.

Create REST API using Lumen video tutorial

  • If you do not want to read the post then you can also go to this video explanation.

  • If you are ok with the written post then proceed.

tools required

We will use the following to create our Restful Web Services.

  • PHP Storm (although you can use any other IDE but I would recommend using it).
  • Lumen (php framework) by Laravel
  • XAMPP (for dev environment)
  • Postman (the rest of the customer to test the API)

I hope you got all the equipment. Let us discuss database design.

Database design

  • Here is my database design. I’m going to do a very simple construction Question Answer Application. So keeping it very simple is the database model that I finalized.
Build rest of api database design
Database design
  • This time you do not need SQL code for the database. Lumen will do this for you. Don’t be confused just keep reading 4

Creating a lumen project

  • Make sure you have the composer installed in your computer.
  • Now go to the directory htdocs of xampp And open command window in the same directory. (You can use shift + right click to open a command window in the specified folder).
  • Now run the following command.
composer create-project laravel/lumen MyQAApp

  • In the above order MyQAApp Is the name of your project. If you want, you can change it to anything you like.
  • Wait for some time after running the command (if you have a slow internet connection it may take a very long time).

Create the rest of your lumen project

  • After the above command is over. You will find a folder with the project name htdocs.
  • Now go to the web browser and try to open Localhost / MyQAApp / public / (Make sure xampp is running and you are using the same project name).

Create the rest of your lumen

  • You need to open this folder as a project in PHP Storm.

Lumen directory structure

  • Once you open the project in PHP Storm, you will see the following directory structure.
Build rest api php storm project
Directory structure
  • You see many folders here but we only need to care about the following.
    Applications: Here we will define the model for performing database operations.
    App / http / controllers: Here we will define our app logic.
    App / http / midwares: We will define API security here.
    Database / Migration: We will define the database schema here.
    way: Here we will define the endpoints for the API.

Database setting

  • First create a database phpmyadmin. You do not need to create a table. Just create a database. (I have created a database by name myqaapp) is.

Create rest api database

  • Now php storm and come back to project in open .env File, and modify it as below.
APP_ENV=local
APP_DEBUG=true
APP_KEY=
APP_TIMEZONE=UTC

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myqaapp
DB_USERNAME=root
DB_PASSWORD=

CACHE_DRIVER=array
QUEUE_DRIVER=sync

  • In the above file, I changed the following.
    DB_DATABASE = yourdatabasename
    DB_USERNAME = database username of xampp (in this case the root)
    DB_PASSWORD = database password (nothing in this case)
    CACHE_DRIVER = array
  • Now we will create database schema in migration.

Building Database Schema

  • Go to php storm See-> Tools Windows-> Terminal.

Build the rest of your opening terminal

  • You will see a terminal window at the bottom.

Creating Migration

  • Let us execute the following commands on the terminal.
php artisan make:migration create_users_table --create=users

  • The above command contains the name of the user table. You need to execute the above command for each table designed in our database. Make sure that you create the migration in the following sequence. Sequence is important because we are working with primary and foreign keys.

The rest of the APIs are causing migration

  • In these files we will design the database schema.

Designing database schema

User schema

  • Start with the first one users_table.php. You will see the following code inside.
<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

  • Inside the method (UP) We will define the schema. We have already created the database, so we need to add some lines inside the method (UP).
  • Modify the code given below.
<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');

            //these 3 fields added
            $table->string('username');
            $table->text('password');
            $table->string('email');


            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

  • In the same way, we will also define the schema for another table. In the above code you can see we have written $ Table-> string (’email’); This means that the table has a new column name E-mail With datatype Wire. You can check the official docs of larvae for a list of available datatips.
  • Lets define schema for the remaining 3 tables in the same way.

Categories Schema

<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('categories');
    }
}

Question schema

<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateQuestionsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('questions', function (Blueprint $table) {
            $table->increments('id');
            $table->string('question');
            $table->integer('category_id')->nullable()->unsigned();
            $table->integer('user_id')->unsigned();
            $table->foreign('category_id')->references('id')->on('categories');
            $table->foreign('user_id')->references('id')->on('users');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('questions');
    }
}

Answer schema

<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateAnswersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('answers', function (Blueprint $table) {
            $table->increments('id');
            $table->string('answer');
            $table->integer('user_id')->unsigned();
            $table->integer('question_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users');
            $table->foreign('question_id')->references('id')->on('questions');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('answers');
    }
}

  • So we have database schema ready. Now let’s do a migration to create a table in MySQL.

Make migration

  • In terminal type php artisans migrate. And the database will be migrated automatically.

Create rest of api migrating database

  • Check now PhpMyAdmin And you will see that the tables are created.

Model making

  • Models will simplify the database. We will use the Laravel Eloquent ORM and model and it will simplify the database operation as before. If you are going to use it then you don’t really need to write a single line of SQL query.
  • But first thing we need to enable Eloquent, because it is not enabled by default.

To enable

  • Go for Bootstrap / app.php. And unlim the following lines.

Build enabling rest of apl

  • Now we will create a model for each database table App Folder. So we will make User.php, gradorie.php, Question.php and Answer.php.

User model

  • come on in the user And modify the model class as below. You can see below that we are defining relationships.
<?php

namespace App;

use IlluminateDatabaseEloquentModel;

class User extends Model 
{
 	public function questions(){
 		return $this->hasMany('AppQuestion');
 	}   
}

Question model

<?php

namespace App;

use IlluminateDatabaseEloquentModel;


class Question extends Model 
{
    public function answers(){
    	return $this->hasMany('AppAnswer');
    }
}

Category model

<?php

namespace App;

use IlluminateDatabaseEloquentModel;


class Category extends Model 
{
    public function questions(){
    	return $this->hasMany('AppQuestion');
    }
}

Answer model

<?php

namespace App;

use IlluminateDatabaseEloquentModel;


class Answer extends Model 
{
    
}

  • Therefore we have defined the models. Now lets create a controller.

Make controller

  • Now we will create the controller. These controllers will perform the actual operation. All controller files will be created inside App / http / controllers.

User controller

  • Create a new php file by name UserController.php. First we need to think about which operation we need for the user. So for this app I have fixed 3 operations.
    1. User Registration: A new user can register to apply.
    2. user login: One can enter the application by providing username and password.
    3. Get my questions: The user can see all the questions that have been asked by that user.
  • So in UserController.php We will define a class that will extend the controller, and inside the class we will define all functions as separate functions.
<?php

namespace AppHttpControllers;

use IlluminateHashingBcryptHasher;
use IlluminateSupportFacadesValidator;
use IlluminateHttpRequest;
use AppUser;


class UserController extends Controller
{

    //this function is used to register a new user
    public function create(Request $request)
    {
        //creating a validator
        $validator = Validator::make($request->all(), [
            'username' => 'required|unique:users',
            'password' => 'required',
            'email' => 'required|unique:users'
        ]);

        //if validation fails 
        if ($validator->fails()) {
            return array(
                'error' => true,
                'message' => $validator->errors()->all()
            );
        }
    
        //creating a new user
        $user = new User();
        
        //adding values to the users
        $user->username = $request->input('username');
        $user->email = $request->input('email');
        $user->password = (new BcryptHasher)->make($request->input('password'));
        
        //saving the user to database
        $user->save();
        
        //unsetting the password so that it will not be returned 
        unset($user->password);

        //returning the registered user 
        return array('error' => false, 'user' => $user);
    }

    //function for user login
    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'username' => 'required',
            'password' => 'required'
        ]);

        if ($validator->fails()) {
            return array(
                'error' => true,
                'message' => $validator->errors()->all()
            );
        }

        $user = User::where('username', $request->input('username'))->first();

        if (count($user)) {
            if (password_verify($request->input('password'), $user->password)) {
                unset($user->password);
                return array('error' => false, 'user' => $user);
            } else {
                return array('error' => true, 'message' => 'Invalid password');
            }
        } else {
            return array('error' => true, 'message' => 'User not exist');
        }
    }

    //getting the questions for a particular user 
    public function getQuestions($id)
    {
        $questions = User::find($id)->questions;
        foreach ($questions as $question) {
            $question['answercount'] = count($question->answers);
            unset($question->answers);
        }
        return array('error' => false, 'questions' => $questions);
    }
}

Question controller

  • For the question we will do the following operations.
    1. Submit a new question.
    2. Get all questions.
    3. Get a specified category of questions.
  • So create a file named QuestionController.php And write the following code.
<?php

namespace AppHttpControllers;

use IlluminateDatabaseEloquentModelNotFoundException;
use IlluminateSupportFacadesValidator;
use IlluminateHttpRequest;
use AppQuestion; 
use AppCategory;

 

class QuestionController extends Controller
{
 
    
    public function create(Request $request){

        $validator = Validator::make($request->all(), [
            'question'=>'required',
            'user_id'=>'required'
        ]);

        if($validator->fails()){
            return array(
                'error' => true,
                'message' => $validator->errors()->all()
            );
        }

        $question = new Question;
        $question->question = $request->input('question');
        $question->user_id= $request->input('user_id');
        $question->category_id= $request->input('category_id');
        $question->save();
        return array('error'=>false, 'question'=>$question);
    }

    public function getAll(){
        $questions = Question::all();

        foreach($questions as $question){
            $question['answercount'] = count($question->answers);
            unset($question->answers);
        }


        return array('error'=>false, 'questions'=>$questions);
    }

    public function getByCategory($category_id){
        try{
            $questions = Category::findOrFail($category_id)->questions; 

            foreach($questions as $question){
                $question['answercount'] = count($question->answers);
                unset($question->answers);
            }

            return array('error'=>false, 'questions'=>$questions);
        }catch(ModelNotFoundException $e){
            return array('error'=>true, 'message'=>'Invalid Category ID');
        }
    }
  
}

Grade controller

  • Create a new file by name Category Controller. FP And write the following code.
<?php

namespace AppHttpControllers;

use IlluminateSupportFacadesValidator;
use IlluminateHttpRequest;
use AppCategory; 

class CategoryController extends Controller
{

	public function create(Request $request){

		$validator = Validator::make($request->all(), [
            'name'=>'required|unique:categories'
        ]);

        if($validator->fails()){
            return array(
                'error' => true,
                'message' => $validator->errors()->all()
            );
        }

        $category = new Category; 
        $category->name = $request->input('name');
        $category->save();

        return array('error'=>false, 'category'=>$category);
	}

}

  • Finally lets create AnswerController.

Answer controller

  • Create a new file named again AnswerController.php And write the following code.
<?php

namespace AppHttpControllers;

use IlluminateSupportFacadesValidator;
use IlluminateHttpRequest;
use AppAnswer; 

class AnswerController extends Controller
{
 
    public function submit(Request $request){

        $validator = Validator::make($request->all(), [
            'answer'=>'required',
            'user_id'=>'required',
            'question_id'=>'required'
        ]);

        if($validator->fails()){
            return array(
                'error' => true,
                'message' => $validator->errors()->all()
            );
        }

        $answer = new Answer;
        $answer->answer = $request->input('answer');
        $answer->question_id= $request->input('question_id');
        $answer->user_id= $request->input('user_id');
        $answer->save();
        return array('error'=>false, 'answer'=>$answer);
    }
}

  • Our controllers are ready, now we will define URL routes to call operations.

Creating URL EndPoints

  • come inside Routes / web.php. And write the following code.
<?php

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/

$app->get('/', function () use ($app) {
    return $app->version();
});


/***
 * The first parameter 'createuser' it is the url address
 * So to call this we will use the URL as BASE URL + createuser
 * 
 * The second parameter is UserController@create 
 * it means we are calling create function which is inside UserController
 * 
 * Using the same for all routes
 ***/
$app->post('createuser', 'UserController@create');
$app->post('createquestion', 'QuestionController@create');
$app->post('submitanswer', 'AnswerController@submit');
$app->post('userlogin', 'UserController@login');
$app->post('createcategory', 'CategoryController@create');
$app->get('categories', 'CategoryController@get');
$app->get('getmyquestions/{user_id}', 'UserController@getQuestions');
$app->get('questions', 'QuestionController@getAll');
$app->get('questions/{category_id}', 'QuestionController@getByCategory');

API test

  • Now lets test all endpoints. For this I am using POSTMAN. You can use any REST client.
  • So open the postman. And write a URL. In my case the BASE URL is http: // localhost / MyQAApp / public / And after that we will add what we have created.
  • So lets test create user First, for this, insert the URL into POSTMAN, choose the request type as POST and add the required parameters. (You can take help from the screenshot below).

 

Build rest of api postman test
create user
  • You can see that it is working fine. In the same way you also need to test all other routes.

Add Basic Authentication

  • Now imagine that we are using this API for our application. And someone gets the URL addresses of our API. What can happen then? Our database can be filled with spam values ​​with URL addresses. So we need some authentication part so that we can only accept requests from the application.
  • There are many security models but to keep it simple I will tell you about adding Basic Authentication.

Creating a MiddleWare

  • come inside App / http / middleware Open more file Authentic, Delete everything and write the following code.
<?php

namespace AppHttpMiddleware;

use Closure;

//defining a username and password
define('USERNAME','belalkhan');
define('PASSWORD', '123456');

class Authenticate
{

    public function handle($request, Closure $next)
    {
		//getting values from headers
		//if the user is authenticated accepting the request
        if($request->header('PHP_AUTH_USER') == USERNAME && $request->header('PHP_AUTH_PW') == PASSWORD){
            return $next($request);
		
		//else displaying an unauthorized message 
		}else{
            $content = array();
            $content['error'] = true; 
            $content['message'] = 'Unauthorized Request';
            return response()->json($content, 401);
        }
    }
}

  • Now we will connect this middleware to all routes. Come in to do this Bootstrap / app.php. And add the following code inside Register middleware Section.
$app->middleware([
    AppHttpMiddlewareAuthenticate::class
 ]);

  • Now try sending the request to POSTMAN again. You will see the following output.

Rest of the unauthorized construction

  • As you can see the error message that the request is an unauthorized request with status code 401. So our API is a bit safer now. To send a request we need a username and password to authorize each request.

Send request with original authentic

  • Postman has an inbuilt option to set basic author headers. Just click on Authorization and choose Original Authentic.

Make the rest of your basic

  • Now enter your API username and password that you have set, and send the request.

Create other API examples

  • You can see that it is working fine now.

Things I leave in this API

  • I left out many things in this API because it is just an example to teach the idea of ​​creating an API. I am mentioning some functions that I have left to simplify it. But if you want to learn, you can try to complete this API.
    1. No user update option.
    2. If there will be no big data then there is no argument that it is not a good idea to bring it at once.
    3. Nobody uplifts and prefers over answers.
  • I pointed out some points, there is still something that can be added. So comment below what should be added on this API.

Create REST API using Laravel Lumen Source Code

  • If you are facing troubles then you can get my source code from the link given below.

So that for all Create Easy API Tutorial friend. I hope you got the idea to create Restful Web Services.

In the next post we will create an Android application for this API using the new Kotlin language.

In the meantime, if you are having any problem or confusion, feel free to leave your comments. If you found this article useful, then do not forget to share. Thank you 4


Source link

About dmtechnolab

Check Also

Simplified Coding

Android Espresso Tutorial – Testing Fragment in Isolation – Android Coding by DMTechnolab

Welcome to another tutorial in the Android test series. And this post is called Android …

Leave a Reply

Your email address will not be published. Required fields are marked *