INNOVATE - CONNECT - CREATE
INNOVATE
CONNECT
CREATE

Who We Are

 
Devamplify is a tech innovation community focused on providing support for individuals that are interested in tackling some of our biggest challenges in the south eastern part of Nigeria, Nigeria and Africa using innovative technology.
 

INNOVATION

Let's work together to create solutions targeted at solving real community issues.

INCUBATION

Leverage on our support, shared office space, meetups and startup trainings to grow your idea.

ACCELERATION

Access training, support and mentoring required to get started in the tech industry.

Membership

Devamplify offers shared office workspace for developers and event space for tech related events. Located along the most accessible road in the city of Awka in Anambra state Nigeria, Devamplify members will be able to acces our meeting areas as well as other office facilities like constatnt power supply and internet at a very discounted rate for their buddig startups

More On Membership

What We Have Been Up To!

gallery image
WordPress at 15 celebration at Devamplify Hub, the most active hub in South East Nigeria
gallery image
Photos from the celebration of WordPress at 15 Anniversary held at the Devamplify Hub
gallery image
Photos from the celebration of WordPress at 15 Anniversary held at the Devamplify Hub
gallery image
More photos from the celebration of WordPress at 15 Anniversary held at the Devamplify Hub
gallery image
Group photograph of attendees at Startup Anambra Masterclass, held at Devamplify Hub
gallery image
Group photograph of some of the speakers and participants at Startup Anambra Masterclass
gallery image
Mimshach Obioha, Pascal Okeke, Michael John, and Kal Chuka in a chat after the event.
gallery image
Nonso Ndigwe speaking on Marketing during the Startup Anambra Masterclass, at Devamplify Hub

Like What We Are Doing?

Are you a software developer, an aspiring developer or a tech enthusiast and interested in building this community with us, join our slack channel to meet other developers and together we will make a great community. You can also follow us on twitter or like our page on facebook.

Startups

WEB HOSTING

B24HOST

B24host provides Web Hosting, Domains Name Registration, Web Design, SSL Security and more to clients in Nigeria and across Africa.

ENVIRONMENT

RECYCLEPRO

RecylePro captures value from waste; recycling them for electricity, data and other benefits to empower Nigeria's young populace.

Recent Blog Posts

Testing Lumen API With PHP Unit Tests

Testing Lumen API With PHP Unit Tests

Posted on: Mon, 11-Jun-2018
Written by: Stephen Jude

Earlier this year I started reading about TDD (Test Driven Development) approach and I began to see the importance of writing unit tests during software development. Good unit tests can help you document and define what you are supposed to do.

To know more about unit test and why it is important check out this thread on stackoverflow.

In this tutorial we are going to build a very simple RESTFul API with Lumen that can GET, POST, PUT and DELETE data from our database. Using our API endpoints, a user can create, view, edit and delete product from the database.

Here is the list of endpoints we are going to build.

    /products [GET] — gets all products.
    /products/id [GET] — gets just a product.
    /products [POST] — add a new product.
    /products/id [PUT] — edit existing product.
    /products/id [DELETE] — delete existing product.

We will make use of Fractal to structure our API response and use PHPUnit to test all our endpoints.

The focus of this tutorial is on how to use PHPUnit to test our endpoint. Our test will check the status code returned by our request and the structure of the response data.


Requirements

    Apache or nginx server
    At least PHP 5.4 release
    MYSQL Database
    Composer

To get started on windows download WAMP, Mac OS — MAMP & Linux — LAMP

 

Setting Up The Development Environment

For the purpose of this tutorial we will be using Lumen 5.4 since it supports PHP 5.6 release. So if you are still using PHP 5.6 release we got you covered, but do well and upgrade to 7.0 or 7.1 release.

Open you terminal and run this command.
composer create-project laravel/lumen productAPI "5.4.*"

Change productAPI to any name of your choice.


Configure the .env File

The next thing you should do after installing Lumen is to rename .env.example file to .env and set your APP_KEY to a random string. Set DB_DATABASE to product_db, DB_USERNAME to your database username and DB_PASSWORD to your database password. Remember to create a database with the name product_db.

To avoid memcached error set CACHE_DRIVER and QUEUE_DRIVER to array

Our .env file should look like this
APP_ENV=local
APP_DEBUG=true
APP_KEY=afdfdhdfdueuekfhhfueyeyjcfh
APP_TIMEZONE=UTC

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=product_db
DB_USERNAME=root
DB_PASSWORD=your_password

CACHE_DRIVER=array
QUEUE_DRIVER=array

 


Writing PHPUnit Test

Unit test helps us to define what we are supposed to do before we start doing it. Lumen has already configured our testing environment for us. The configuration file is phpunit.xml located inside the project directory. All our test will be inside the tests directory.

Create a new test file inside this directory. Name it ProductTest.php Our test file will extend the TestCase class. With this class we now have access to all methods we will use to test our endpoints.

Here is our test file

<?php
class ProductTest extends TestCase
{
    /**
     * /products [GET]
     */
    public function testShouldReturnAllProducts(){
        $this->get("products", []);
        $this->seeStatusCode(200);
        $this->seeJsonStructure([
            'data' => ['*' =>
                [
                    'product_name',
                    'product_description',
                    'created_at',
                    'updated_at',
                    'links'
                ]
            ],
            'meta' => [
                '*' => [
                    'total',
                    'count',
                    'per_page',
                    'current_page',
                    'total_pages',
                    'links',
                ]
            ]
        ]);
        
    }
    /**
     * /products/id [GET]
     */
    public function testShouldReturnProduct(){
        $this->get("products/2", []);
        $this->seeStatusCode(200);
        $this->seeJsonStructure(
            ['data' =>
                [
                    'product_name',
                    'product_description',
                    'created_at',
                    'updated_at',
                    'links'
                ]
            ]    
        );
        
    }
    /**
     * /products [POST]
     */
    public function testShouldCreateProduct(){
        $parameters = [
            'product_name' => 'Infinix',
            'product_description' => 'NOTE 4 5.7-Inch IPS LCD (3GB, 32GB ROM) Android 7.0 ',
        ];
        $this->post("products", $parameters, []);
        $this->seeStatusCode(200);
        $this->seeJsonStructure(
            ['data' =>
                [
                    'product_name',
                    'product_description',
                    'created_at',
                    'updated_at',
                    'links'
                ]
            ]    
        );
        
    }
    
    /**
     * /products/id [PUT]
     */
    public function testShouldUpdateProduct(){
        $parameters = [
            'product_name' => 'Infinix Hot Note',
            'product_description' => 'Champagne Gold, 13M AF + 8M FF 4G Smartphone',
        ];
        $this->put("products/4", $parameters, []);
        $this->seeStatusCode(200);
        $this->seeJsonStructure(
            ['data' =>
                [
                    'product_name',
                    'product_description',
                    'created_at',
                    'updated_at',
                    'links'
                ]
            ]    
        );
    }
    /**
     * /products/id [DELETE]
     */
    public function testShouldDeleteProduct(){
        
        $this->delete("products/5", [], []);
        $this->seeStatusCode(410);
        $this->seeJsonStructure([
                'status',
                'message'
        ]);
    }
}

Remember that extending TestCase class give us access to all the methods we are going to use for our test. These methods includes: get, post, put and delete.

The get method takes only two arguments. The URL we are requesting data from and an array that contains the request header like access token etc. In this tutorial we will leave the header empty.


$this->get($url, $header);

The post, put and delete methods takes three arguments. The URL, the request parameters and the request header.

$this->post($url, $parameters, $header);
$this->put($url, $parameters, $header);
$this->delete($url, $parameters, $header);
Here is a sample parameter and a header
$parameters = ['param' => 'value'];
$header = [ 'HTTP_Authorization' => 'value'];

Our test method does three basic things, using the get, post, put and delete methods it make a request to an endpoint.

$this->get("products", []);
$this->get("products/2", []);
$this->post("products", $parameters, []);
$this->put("products/4", $parameters, []);
$this->delete("products/5", [], []);

After making request, it checks if the request returns the expected status code.

$this->seeStatusCode(200);
$this->seeStatusCode(410);

Finally it checks if the data returned from our request follows the expected structure .

$this->seeJsonStructure(
     ['data' =>
         [
           'product_name',
           'product_description',
           'created_at',
           'updated_at',
           'links'
         ]
     ]
);
Running Tests

To run your tests, simply execute the vendor/bin/phpunit command from your terminal. To test each method separately run this command


vendor/bin/phpunit --filter=testShouldReturnAllProducts

This command test only the testShouldReturnAllProducts() method.

For now all our tests will fail. So let start working for all these tests to pass.

Configure The Bootstrap File

The bootstrap file is located in bootstrap directory. Open the app.php and uncomment the following:

$app->withEloquent();
$app->withFacades();
Creating Migration Files

We are going to create only one table, the product table. Run this command on your terminal to create the product migration file.
php artisan make:migration create_products_table

Here is our migration file

<?php
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->string('product_name');
            $table->text('product_description');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Running Migrations

Run this command to create product table in our database.
php artisan migrate


Creating Model

Inside the app directory create a model file and name it Product.php.

<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Product extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'product_name', 'product_description',
    ];
}


Inserting Fake Data And Seeding the Database

Let use Faker library to generate fake data. We are going to use ModelFactory.php located inside database/factories/ directory.

<?php
$factory->define(AppProduct::class, function (FakerGenerator $faker) {
    return [
        'product_name' => $faker->word,
        'product_description' => $faker->text,
    ];
});

Inside the database/seeds/ directory open DatabaseSeeder.php file and call the model factory to create 10 products.

<?php
use IlluminateDatabaseSeeder;
class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //create 10 products
        factory(AppProduct::class, 10)->create();
    }
}

 

Running Seeders

Now, let seed the database with fake data. Run the following command on your terminal
php artisan db:seed


Installing Fractal

Fractal provides a presentation and transformation layer for complex data output, the like found in RESTful APIs, and works really well with JSON. Thats how they put it and that how it works. Here is the documentation

Run this command to install Fractal
$ composer require league/fractal


Creating Routes

Go to routes directory, open web.php file. We are going to define all our API routes inside this file.

<?php
$app->get('/', function () use ($app) {
    return $app->version();
});
//product routes
$app->get('products', '[email protected]');
$app->get('products/{id}', '[email protected]');
$app->put('products/{id}', '[email protected]');
$app->post('products', '[email protected]');
$app->delete('products/{id}', '[email protected]');

 

Creating Transformer

Create a new folder inside the app directory and name it Transformers. Inside this new folder create a new file and name it ProductTransformer.php. We will use the fractal class to transform our response data.

<?php
namespace AppTransformers;
use AppProduct;
use LeagueFractal;
class ProductTransformer extends FractalTransformerAbstract
{
    public function transform(Product $product)
    {
        return [
            'id'      => (int) $product->id,
            'product_name'   => $product->product_name,
            'product_description'    =>  $product->product_description,
            'created_at'    =>  $product->created_at->format('d-m-Y'),
            'updated_at'    =>  $product->updated_at->format('d-m-Y'),
            'links'   => [
                [
                    'uri' => 'products/'.$product->id,
                ]
            ],
        ];
    }
}

 

Creating Controller

We will create 1 controller inside the app/Http/Controllers directory and name it ProductsController.php.

We will create index, show, update, store, destroy and customResponse. All this methods will handle route request except customResponse method that we will use to return success or error response.

We will use the product model, fractal classes and our product transformer class that will transform our response data.

<?php
namespace AppHttpControllers;
use AppProduct;
use IlluminateHttpRequest;
use LeagueFractal;
use LeagueFractalManager;
use LeagueFractalResourceItem;
use LeagueFractalResourceCollection;
use LeagueFractalPaginationIlluminatePaginatorAdapter;
use AppTransformersProductTransformer;
class ProductsController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    private $fractal;
    public function __construct()
    {
        $this->fractal = new Manager();  
    }
    /**
     * GET /products
     *
     * @return array
     */
    public function index(){
        $paginator = Product::paginate();
        $products = $paginator->getCollection();
        $resource = new Collection($products, new ProductTransformer);
        $resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
        return $this->fractal->createData($resource)->toArray();
    }
    public function show($id){
        $product = Product::find($id);
        $resource = new Item($product, new ProductTransformer);
        return $this->fractal->createData($resource)->toArray();
    }
    public function store(Request $request){
        //validate request parameters
        $this->validate($request, [
            'product_name' => 'bail|required|max:255',
            'product_description' => 'bail|required',
        ]);
        $product = Product::create($request->all());
        $resource = new Item($product, new ProductTransformer);
        return $this->fractal->createData($resource)->toArray();
    }
    public function update($id, Request $request){
        //validate request parameters
        $this->validate($request, [
            'product_name' => 'max:255',
        ]);
        //Return error 404 response if product was not found
        if(!Product::find($id)) return $this->errorResponse('product not found!', 404);
        $product = Product::find($id)->update($request->all());
        if($product){
            //return updated data
            $resource = new Item(Product::find($id), new ProductTransformer);
            return $this->fractal->createData($resource)->toArray();
        }
        //Return error 400 response if updated was not successful        
        return $this->errorResponse('Failed to update product!', 400);
    }
    public function destroy($id){
        
        //Return error 404 response if product was not found
        if(!Product::find($id)) return $this->errorResponse('Product not found!', 404);
        //Return 410(done) success response if delete was successful
        if(Product::find($id)->delete()){
            return $this->customResponse('Product deleted successfully!', 410);
        }
        //Return error 400 response if delete was not successful
        return $this->errorResponse('Failed to delete product!', 400);
    }
    public function customResponse($message = 'success', $status = 200)
    {
        return response(['status' =>  $status, 'message' => $message], $status);
    }
}

 

Running Tests

Before we run our test again, first we will refresh and seed our database.

php artisan migrate:refresh //recreate the database tables
php artisan db:seed  //seed the database
vendor/bin/phpunit //test all our endponits

You can also test each method in our test file using the filter flag followed by the name of the method.
vendor/bin/phpunit --filter=testShouldCreateProduct

 

Conclusion

Now you know how to write a basic unit test for API and you can use this approach to make your code more easier to debug and maintain.

Here is the github repostory for this tutorial

For more on unit testing, check out these cool stuffs.

Lumen Unit Test Documentation

Laravel Unit Test Documentation

PHPUnit Documentation

From South East Nigeria To The World

From South East Nigeria To The World

Posted on: Wed, 23-May-2018
Written by: Devamplify

Inline with the mission of creating a community of world class software developers in the South Eastern part of Nigeria as well as incubate and accelerate them, on Wednesday the 17th day of May 2018, we inducted the first cohort for the DevAmplify Accelerate Internship 2018.

The event which brought interns from across South East states in Nigeria will give birth to fresh Startups and innovative ideas and till the next six months, we will be bringing you startup journeys of this brilliant minds.

The twenty four aspiring developers were put into eight teams of three in a team, where they are going to be building a project by the end of their training and launching their startup based on their project.

 

Note that DevAmplify Hub is the foremost Technology and Startup Incubation Hub in Anambra state. Located at Aroma, beside UBA, opposite Anambra Broadcasting Service (ABS), Awka - the capital city of Anambra State.

We are passionate about partnering with other startups ecosystem to build a community of creatives in not just Anambra State or SouthEast but in Nigeria and Africa at Large.

Keep in touch with us as we shall be bringing you more updates as the days go by. Cheers!

Deep dive into middlewares in Laravel

Deep dive into middlewares in Laravel

Posted on: Mon, 16-Apr-2018
Written by: Nwanze Franklin

What is a Laravel middleware? It is a feature in Laravel which provides a mechanism for filtering HTTP requests entering your application. This allows you to hook into Laravel request processing work flow to perform some kind of logic that decides how your application works.

What would you use middleware for?

  • Protecting your routes
  • Setting headers on HTTP responses
  • Logging requests to your application
  • Sanitizing incoming parameters
  • Enable site-wide maintenance mode
  • Manipulating responses generated by your application

How to create a custom middleware?

Creating a middleware in Laravel is as simple as running the following command

php artisan make:middleware <MiddlewareName>
//MiddlewareName should be replaced with actual name of the middleware

This creates a middleware with the specified name in the middleware folder located in app. Luckily, Laravel scaffolds the basic things needed to start customizing your middleware.

<?php
namespace AppHttpMiddleware;
use Closure;
class RedirectIfSuperAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

Notice the handle function which accepts two parameters $request and $next . The $request parameter holds the incoming request URI in your application while $next parameter is used to pass the request deeper into the application. The logic needed is written within the handle function and that brings us to types of middleware-before middleware and after middleware.

Before middleware as the name suggests handles some set of logic before forwarding the request deeper into the application. On the other hand after middleware runs after the request has been handled by the application and the response built.

Before middleware:

<?php
namespace AppHttpMiddleware;
use Closure;
class RedirectIfSuperAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        //Your logic goes here
        return $next($request);
    }
}

After middleware:

<?php
namespace AppHttpMiddleware;
use Closure;
class RedirectIfSuperAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        //Your logic goes here e.g return redirect('/)

        return $response;
    }
}

Categories of Middleware

  • Global middleware
  • Route middleware

Global middlewares run for every single request that hits the application. Laravel comes with most of these middlewares such as ValidatePostSizeTrimStrings,CheckForMaintenanceMode etc.

Route middlewares run only on routes they are attached to e.g redirectIfAuthenticated.

Registering a Middleware

Any middleware created has to be registered as that is the only way Laravel knows that such exists. To register a middleware simply open the file named kernel.php which is located inside Http folder like so:

This file contains list of all registered middlewares thatkernel.php location on Laravel come with Laravel by default. it contains three major arrays which include $middleware , $middlewareGroups and $routeMiddleware

<?php
namespace AppHttp;
use IlluminateFoundationHttpKernel as HttpKernel;
class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode::class,
        IlluminateFoundationHttpMiddlewareValidatePostSize::class,
        AppHttpMiddlewareTrimStrings::class,
        IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull::class,
        AppHttpMiddlewareTrustProxies::class,
    ];
    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            AppHttpMiddlewareEncryptCookies::class,
            IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
            IlluminateSessionMiddlewareStartSession::class,
            // IlluminateSessionMiddlewareAuthenticateSession::class,
            IlluminateViewMiddlewareShareErrorsFromSession::class,
            AppHttpMiddlewareVerifyCsrfToken::class,
            IlluminateRoutingMiddlewareSubstituteBindings::class,
        ],
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];
    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => IlluminateAuthMiddlewareAuthenticate::class,
        'auth.basic' => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class,
        'bindings' => IlluminateRoutingMiddlewareSubstituteBindings::class,
        'can' => IlluminateAuthMiddlewareAuthorize::class,
        'guest' => AppHttpMiddlewareRedirectIfAuthenticated::class,
        'throttle' => IlluminateRoutingMiddlewareThrottleRequests::class,
        //the just created middlware
        'superadmin' => AppHttpMiddlewareRedirectIfSuperAdmin::class, 
    ];
}

The $middleware array holds global middlewares which runs for every single HTTP request to the application, so if you want a middleware to run for every request you should register it here. The $middlewareGroups makes it possible to register middlewares in groups making it easier to attach lots of middlewares to a route by using the group name. The $routeMiddlewarearray holds individual registered middlewares.

Assigning a Middleware

Once a middleware is registered it can be attached to a route in two major ways

  • Through the constructor method in a controller
  • Through the route

Middleware assignment through constructor

Middleware assignment via a constructor on a controller gives more flexibility as it offers two important functions except($parameters) and only($parameters) which can be used to prevent or allow the middleware to apply to some helper functions in that controller. Without using the helper functions the middleware applies to every single function on that controller.

<?php
use IlluminateHttpRequest;

class ForumController extends Controller
{

    public function __construct(){
      /**in this case the middleware named auth is applied
       to every single function within this controller
       */
        $this->middleware('auth');
    }

    public function viewForum(){

      return view('index');
    }

    public function edit($id){

    }

    public function delete($id){

    }

}

With the except and only functions we can select which functions the middleware will apply to as shown below:

<?php
use IlluminateHttpRequest;

class ForumController extends Controller
{

    public function __construct(){
      /**the authentication middleware here applies to all functions but
       viewForums() and viewForumDetails() and the opposite of this happens
       when you use only()
       */
        $this->middleware('auth')->except(['viewForums', 'viewForumDetails']);
    }

    public function viewForums(){

      return view('index');
    }

    public function edit($id){

    }

    public function delete($id){

    }

    public function viewForumDetails(){

    }
}

Middleware assignment through routes

Provided a middleware has been registered in can be attached to the route directly as show below:

<?php
//method 1
Route::get('admin/profile', function () {
  //action
})->middleware('auth');

/**method 2
or using the fully qualified class name like so:
*/
use AppHttpMiddlewareCheckAge;

Route::get('admin/profile', function () {
    // action
})->middleware(CheckAge::class);

//method 3
Route::group(['middleware' => ['web']], function () {
    //action
});

N:B Middleware groups can be assigned to a route the same way as a single middleware

Middleware Parameters

Additional parameters can be passed to a middleware. A typical example is where each user id is assigned to a role and the middleware checks the role of a user to determine if he/she has access to the requested URI. Parameters can be passed to a middleware as shown below:

<?php
//First method (Through route)
Route::get('admin/profile', function () {
  //action
})->middleware('auth:<role>'); //<role> here should be replaced by whatever parameter the user intends to pass.

//Second method (Through a controller)
use IlluminateHttpRequest;

class ForumController extends Controller
{

    public function __construct(){
        $this->middleware('auth:<role>');
    }
  }

Multiple parameters can be passed to a middleware by separating each parameter by a comma.

<?php
Route::get('admin/profile', function () {
  //action
})->middleware('auth:<role>,<age>,<country>'); //<role>, <age>, <country> here should be replaced by whatever parameters the user intends to pass.

These parameters are passed to the handle function of the middleware after the $next variable.

<?php
class RedirectIfSuperAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $role, $age, $country)
    {   
        //Logic for the middleware using the parsed parameters
        return $next($request);
    }
}

Summary

To create a middleware you go through the following processes

  • Create the middleware with artisan command php artisan make:middleware <Middleware Name>.
  • Register the middleware in kernel.php located in the app→Http folder
  • Write your logic in the created middleware
  • Assign middleware to a route or controller

Conclusion

Laravel middlewares make it easier to protect our routes, sanitize input and do a whole lot of other stuffs without writing so much logic. Checkout the official Laravel documentation here for more features of middlewares and most importantly practice.

How to set up a React.js/TypeScript project using create-react-app

How to set up a React.js/TypeScript project using create-react-app

Posted on: Mon, 16-Apr-2018
Written by: Chidume Nnamdi

Being an Angular developer, I am used to writing codes in TypeScript which I love so much because of TypeScript (a strict syntactical super-set of JavaScript), adds optional static typing to your codes. Recently, I started working on how to transition my Angular/TypeScript projects into React/TypeScript. After scouring the web, I found tons of articles on how to setup React/TypeScript project using Webpack, they were very stressful and brain-racking. I fine-tuned my search and I found out how you could easily setup a React/TypeScript project with zero stress using create-react-app and react-scripts-ts.


Why is this important
Suppose you want to start a new project with React.js and because you are a good software developer, you want to use npm, babel and Webpack. what comes to mind is

Where do I start?
Before create-react-app you had to search and try an infinite amount of boilerplates and example repositories to finally had a mediocre setup after two days of wasted time.
Now it’s easier .

Introduction
We will learn how to create a React/TypeScript project using the create-react-app utility. By the end, we’ll have

* a project with React and TypeScript
We’ll use the create-react-app tool to quickly get set up.I assume that you’re already using Node.js with npm.

Install create-react-app
First, install the global package.

npm install -g create-react-app
Create our new project
We’ll create a new project called myreactapp:

create-react-app myreactapp — scripts-version=react-scripts-ts
* create-react-app is a global command-line utility that you use to create new projects
* react-scripts-ts is a development dependency in the generated project to take the standard create-react-app project and bring TypeScript into the mix.
The create-react-app — scripts-version=react-scripts-ts command will proceed to create the myreactapp folder and install the dependencies in the package.json file it generated.

Your project layout should look like this.

myreactapp/
├─ .gitignore
├─ node_modules/
├─ public/
├─ src/
 | — — index.tsx 
 | — — registerServiceWorker.ts
 | — — logo.svg
 | — — App.tsx
 | — — App.test.tsx
 | — — App.css
 | — — index.css
 | — — assets/
├─ package.json
├─ tsconfig.json
└─ tslint.json
* tsconfig.json contains TypeScript-specific options for our project.
* tslint.json stores the settings that our linter, TSLint, will use.
* package.json contains our dependencies, as well as some shortcuts for commands we’d like to run for testing, previewing, and deploying our app.
* public contains static assets like the HTML page we’re planning to deploy to, or images. You can delete any file in this folder apart from index.html.
* src contains our TypeScript and CSS code.
 *index.tsx is the entry-point for our file, and is mandatory.


Running the project
Ok, now that we are done with the setup. lets fire up our application. First, move into the project folder myreactapp.

cd myreactapp


Then, run the command

npm run start
This runs the start script specified in our package.json, and will spawn off a server which reloads the page as we save our files. Typically the server runs at http://localhost:3000, but should be automatically opened for you.

You can now navigate your favorite browser to localhost:3000 to see our application in action.

Testing the project

Testing is also just a command away:

npm run test


Creating a production build
When running the project with npm run start, we didn’t end up with an optimized build. Typically, we want the code we ship to users to be as fast and small as possible. Certain optimizations like minification can accomplish this, but often take more time. We call builds like this “production” builds (as opposed to development builds).

To run a production build, just run

npm run build
This will create an optimized JS and CSS build in ./build/static/js and ./build/static/css respectively.

You won’t need to run a production build most of the time, but it is useful if you need to measure things like the final size of your app.

Conclusion
You can see that create-react-app is a powerful command-line tool that simplifies the creation of React/TypeScript projects.

I can’t emphasize how useful and important create-react-app is for the ecosystem.

The first and obvious benefit is being able to quickly create new projects without having to think about build infrastructure, which is honestly the most painful part of building a modern React project. create-react-app makes all the hard choices for you and gives you a reasonable set of defaults to work with.

I can’t thank the team behind this little tool enough for making it so easy and so much fun to build React applications!

You can find the full source code at my Github repo.

subscribe to our newsletter

You Can Find Us Here