apt get life

Life around technology

  • Technology
    • Guides
    • Linux
    • Development
      • Laravel
    • Misc
    • Raspberry Pi
  • Writing
  • Crafts
    • Crochet
    • Model Making
    • Painting
  • Privacy Policy
You are here: Home / Archives for Dingo API

Getting started with Laravel 5 & Dingo API: 4. Transformers

2016/04/01 by sudo

Okay, so the last few lessons have got us up to the point where we’re able to send and receive data to the API, but there are some problems that need to be thought about:

  1. We’re exposing our database architecture – people can see orders have fields “order_ref”, “recipient_id”, etc.
  2. Our index functions are using “all()”, so they get all results from the database.
  3. We’re not validating our data before adding it to the database.
  4. We’re not authenticating users.

Lets star addressing these.

Transformers

Transformers are often used in APIs to obscure and abstract the database later from the responses provided to users. What this means is we “transform” what our database record field names are, and turn them into something else. Say in our database we were storing a field “recipient_name”. Instead of the API returning this to the user on a get request, we could use a transformer to return a different field name “name” for example. This obscures our database architecture so we’re not giving away our field names. Additionally, the abstraction here means that if we change our database architecture we’re not relying on API users to change their tools or utilities as well. We can change the database field names without worrying about what users are doing.

Variants Transformer

Once again, I’m going to start with the Variants as this is the smallest part of the API. All we do here is get variants, we don’t allow them to be added, updated or deleted. I’m going to start by looking at my project structure. At the moment we should have Http/Controllers/api and all of the controllers should be within this. It doesn’t really make sense to put transformers here, as they’re not controllers. Instead, I think we should make a new folder in the app directory, and lets version it too, incase different versions of the API use different transformers

mkdir app/Transformers
mkdir app/Transformers/V1

Now lets make a new VariantsTransformer.php file in that directory:

touch app/Transformers/V1/VariantsTransformer.php

Open that file in Atom and lets make our transformer

<?php

namespace App\Transformers\V1;

// We need to reference the Variants Model
use App\Variants;

// Dingo includes Fractal to help with transformations
use League\Fractal\TransformerAbstract;

class VariantsTransformer extends TransformerAbstract
{
    public function transform(Variants $variant)
    {
            // Specify what elements are going to be visible to the API
            return [
        'id' => (int) $variant->id,
                'size' => $variant->size,
                'brand' => $variant->brand,
                'type' => $variant->type,
                'color' => $variant->colour,
                'design' => $variant->design,
        ];
    }
}

All we’re doing here is transforming our Database collection into an array and returning it. The left hand side of the array define the keys that will be used for the JSON response. The right hand side gets the variant fields from the database. What this empowers you to do is hide database fields – like created at – so there’s no risk they’ll be visible to the API. Only items in this array will be returned in API requests. The next key advantage is that the variant database field name doesn’t have to match the API field name. This means that if there’s a major database update that needs to take place, you can update the transformer and not have to ask customers to re-map everything in their APIs.

In the VariantsController, we need to change our functions to adopt the new transformer

use App\Transformers\V1\VariantsTransformer;
public function index()
{
    // Return variants via the Variants Transformer.
    return $this->collection(Variants::all(), new VariantsTransformer);
}
public function show($id)
{
    return $this->item(Variants::find($id), new VariantsTransformer);
}

I’ve added the show function here to return an individual variant instead of a collection. You’ll also need to add the route for it to work:

$api->get('/variants/{id}', 'App\Http\Controllers\api\VariantsController@show');

Now when you call the variants controller in postman, you should see array values coming through as keys in JSON, not database field names.

Following this theme we need to update the Items controller, as well as creating an ItemsTransformer, and the orders controller along with an OrdersTransformer.

ItemsTransformer:

<?php

namespace App\Transformers\V1;

// We need to reference the Items Model
use App\Items;

// Dingo includes Fractal to help with transformations
use League\Fractal\TransformerAbstract;

class ItemsTransformer extends TransformerAbstract
{
    public function transform(Items $item)
    {
        // specify what elements are going to be visible to the API
        return [
            'id' => (int) $item->id,
            'item_ref' => $item->item_ref,
            'quantity' => (int) $item->quantity,
            'variant_id' => (int) $item->variant_id,
        ];
    }

    public function deform(Items $item)
    {
        // specify what elements are going to be visible to the API
        return [
            'id' => (int) $item->id,
            'item_ref' => $item->item_ref,
            'quantity' => (int) $item->quantity,
            'variant_id' => (int) $item->variant_id,
        ];
    }
}

ItemsController:

// At the top of the file, include the items tranformer
use App\Transformers\V1\ItemsTransformer;


// Update the index function to use the ItemsTransformer
public function index()
    {
        return $this->collection(Items::all(), new ItemsTransformer);
    }  

// Update the show function to use the items transformer
public function show($id)
    {
        return $this->item(Items::find($id), new ItemsTransformer);
    }

OrdersTransformer:

<?php

namespace App\Transformers\V1;

// We need to reference the Orders Model
use App\Orders;

// Dingo includes Fractal to help with transformations
use League\Fractal\TransformerAbstract;

class OrdersTransformer extends TransformerAbstract
{
    public function transform(Orders $order)
    {
        // specify what elements are going to be visible to the API
        return [
            'id' => (int) $order->id,
            'order_ref' => $order->order_ref,
            'recipient_id' => $order->recipient_id,
            'shipping_method' => $order->shipping_method,
        ];
    }

    public function deform(Orders $order)
    {
        // specify what elements are going to be visible to the API
        return [
            'id' => (int) $order->id,
            'order_ref' => $order->order_ref,
            'recipient_id' => $order->recipient_id,
            'shipping_method' => $order->shipping_method,
        ];
    }
}

OrdersController:

// Include the orders transformer
use App\Transformers\V1\OrdersTransformer;


// change the index function to use the transformer
public function index()
    {
        return $this->collection(Orders::all(), new OrdersTransformer);
    }

// Change the show function to use the transformer
public function show($id)
    {
        return $this->item(Orders::find($id), new OrdersTransformer);
    }

 

Save all of your work, git commit it if you’re being safe (I won’t show you how to do that now, you know how by now!) and run php artisan serve in order to start the local webserver. Use Postman to send requests to see if your updates are working.

 

One thing to note is that this only transforms the output of our database. Your incoming requests are not handled via the transformer. This is due to the design of fractal, and there is a discussion about it here if you’re interested. Instead of “transforming” input in this way, it’s suggested that models and validation are used instead. Next time we’ll look at running some validation on the input we’re sending to create new orders and order items, as well as working out how to apply the API architecture to the models.

 

Filed Under: Development, Laravel, Technology Tagged With: API, Dingo API, Getting started with Laravel 5 & Dingo API, Laravel, larvel 5, Transformers

Getting started with Laravel 5 & Dingo API: 3. Controllers

2016/03/24 by sudo

This is part 3 of the Laravel 5 & Dingo API series, in which we’re building an API to receive orders from 3rd parties and ship them to recipients. Last time we covered setting up the database, creating migrations and setting up models. This time we’re going to focus on Laravel’s controllers and how we get them working with Dingo API in order to create, read and update data stored in our database.

Controllers

I’m going to start with a variant controller as it has more information that can be returned with a get request and we wouldn’t allow 3rd parties accessing the API to create any variants. This makes it much simpler to build.

With Dingo API, we should specify a base controller to pull all of the helper functions into our individual controllers using inheritance. To do this run:

php artisan make:controller api\\BaseController

Open the BaseController.php file in Atom and add edit it to look like the following:

<?php

namespace App\Http\Controllers\api;

use Dingo\Api\Routing\Helpers;
use Illuminate\Routing\Controller;

class BaseController extends Controller
{
    use Helpers;
}

This is simply inheriting the Controller class, then using the Helpers and creating a new BaseClass to extend from in our API.

We’re going to create a VariantsController, and to keep things organised lets also make it in a subfolder of the application. From the command line run:

php artisan make:controller api\\VariantsController --resource

Now open the controller in Atom and after the use statements at the top of the file add one for the Variants model:

use App\Variants;

You’ll notice because we specified the “–resource” flag at the end of our command line action, the controller has been populated with a skeleton framework of RESTful functions. In the “index” function lets add some code to return all of our variants from the database:

public function index()
{
   return $this->response->array(Variants::all());
}

Before we can test this, lets update our routes.php file to use the new controller:

$api = app('Dingo\Api\Routing\Router');

$api->version('v1', function ($api) {
    $api->get('/', function() {
        return ['test' => true];
    });
    $api->get('/variants', 'App\Http\Controllers\api\VariantsController@index');
});

So, now if you navigate to /api/variants (http://localhost:8000/api/variants/) you should get Dingo API returning all variants in the database. (note you may need to run php artisan serve from the command line first, and if you didn’t seed the database you’ll get an empty response [] ). If you didn’t seed your database, why not add some records and see what responses you get, for example I’ve added a variant and the response is now:

{
  "variants": [
    {
      "id": 1,
      "size": "small",
      "brand": "fashion",
      "type": "hoodie",
      "colour": "black",
      "design": "blank",
      "created_at": "-0001-11-30 00:00:00",
      "updated_at": "-0001-11-30 00:00:00"
    }
  ]
}

At this point, we know our routing is working, and that we’re able to connect to and query a database as well as returning a response to the user. Lets create the Orders and Items controllers:

php artisan make:controller api\\ItemsController --resource
# Controller created successfully.
php artisan make:controller api\\OrdersController --resource
# Controller created successfully.

Lets fill in the functionality to get all items first. Open up the ItemsController in Atom and add the use statement, update it to use the dingo base controller as well as the index function code:

use App\Items;

class ItemsController extends BaseController
public function index()
{
   return $this->response->array(Items::all());
}

While we’re in the items controller, lets add the ability to find a single item in the show method

public function show($id)
{
    return $this->response->array(Items::find($id));
}

As part of the URL, we will pass the item ID, which allows us to do a database search for that item and return the response. If no item is found it’ll return an empty array.

We can save items like so:

public function store(Request $request)
{
    $item = new Items;

    $item->item_ref = $request->input('item_ref');
    $item->quantity = $request->input('quantity');
    $item->variant_id = $request->input('variant_id');

    $item->save();
}

We can also allow updates for an item:

public function update(Request $request, $id)
{
    $item = Items::find($id);

    $item->item_ref = $request->input('item_ref');
    $item->quantity = $request->input('quantity');
    $item->variant_id = $request->input('variant_id');

    $item->save()
}

And finally delete an item:

public function destroy($id)
{
   $item = Items::find($id);
   if ($item->delete()) {
            return $this->response->array(['id' => $id, 'status' => 'deleted']);
   }
}

in the routes.php file, add the methods that we want for the items controller

    // Items
    $api->get('/items', 'App\Http\Controllers\api\ItemsController@index');
    $api->post('/items', 'App\Http\Controllers\api\ItemsController@store');
    $api->get('/items/{id}', 'App\Http\Controllers\api\ItemsController@show');
    $api->patch('/items/{id}', 'App\Http\Controllers\api\ItemsController@update');
    $api->destroy('/items/{id}', 'App\Http\Controllers\api\ItemsController@destroy');

Now you should be able to use Postman to create items:

POST | http://localhost:8000/api/items/

{
    "item_ref": "Test1",
    "quantity": 5,
    "variant_id": 1
}

Select items

GET | http://localhost:8000/api/items/

{
  "items": [
    {
      "id": 1,
      "item_ref": "Test1",
      "quantity": "100",
      "variant_id": "1",
      "created_at": "2016-03-09 16:00:52",
      "updated_at": "2016-03-09 16:07:34"
    }
]

update items

PATCH | http://localhost:8000/api/items/1

{
    "item_ref": "Test1",
    "quantity": 100,
    "variant_id": 1
}

and delete items:

DELETE | http://localhost:8000/api/items/2

{
  "id": "2",
  "status": "deleted"
}

Have a play with the items controller and Postman to make sure your routes and actions are working as expected before moving on. These implementations are not perfect, but it’s enough to get started. Later we’ll see how we can perform validation and even use transformers to alter requests.

The Orders Controller

The orders controller is going to be a duplicate of the items controller to begin with. All of the functionality we added into it we will add into this.

use App\Orders;

class OrdersController extends BaseController

Adding the index method to list all orders

public function index()
{
    return $this->response->array(Orders::all());
}

Adding the store method

public function store(Request $request)
{
    $order = new Orders;

    $order->order_ref = $request->input('order_ref');
    $order->recipient_id = $request->input('recipient_id');
    $order->shipping_method = $request->input('shipping_method');

    if ( $order->save() ) {
        return $this->response->created();
    } else {
        return $this->response->errorBadRequest();
    }
}

Adding the show method

public function show($id)
{
    return $this->response->array(Orders::find($id));
}

The update method

public function update(Request $request, $id)
{
    $order = Orders::find($id);
    $order->order_ref = $request->input('order_ref');
    $order->recipient_id = $request->input('recipient_id');
    $order->shipping_method = $request->input('shipping_method');

    $order->save();
}

and the destroy method

public function destroy($id)
{
    $order = Orders::find($id);
    if ($order->delete()) {
        return $this->response->array(['id' => $id, 'status' => 'deleted']);
    }
}

Finally adding the routes to routes.php

// Orders
$api->get('/orders', 'App\Http\Controllers\api\OrdersController@index');
$api->post('/orders', 'App\Http\Controllers\api\OrdersController@store');
$api->get('/orders/{id}', 'App\Http\Controllers\api\OrdersController@show');
$api->patch('/orders/{id}', 'App\Http\Controllers\api\OrdersController@update');
$api->delete('/orders/{id}', 'App\Http\Controllers\api\OrdersController@destroy'

Now is a good time to commit what we’ve done in git, before moving onto refactoring it.

git add -A
git commit -m "created items, orders and variants controllers with basic functionality"

Filed Under: Development, Laravel, Technology Tagged With: API, Dingo API, Getting started with Laravel 5 & Dingo API, Laravel, larvel 5

Getting started with Laravel 5 & Dingo API: 2. Databases and Migrations

2016/03/17 by sudo

This is part 2 of the Laravel 5 & Dingo API series, in which we’re building an API to receive orders from 3rd parties and ship them to recipients. Last time we covered setting up the environment and making a test API call using Dingo API. This time around, we’ll be looking at what the database architecture could be like, and how we create it with migrations and setting up models with Eloquent ORM in Laravel to allow the API to access our database.

Creating a Database

As with most applications you’ll ever write or interact with, the database is key and it’s design and organisation will be wholly dependent on the application you’re crafting. Right now, I’m going to look at an order API. Lets ponder the database architecture for a moment.

What information do we need to store in order to achieve an order API?

  • Who’s ordered something (eg the “customer” that we’re going to bill, possibly including billing information)
  • Where are we shipping it to
  • What items have been ordered
    • size
    • colour
    • brand
    • type
    • design
  • How many items have been ordered
  • What status an order is (has it been dispatched)

We’re going to have an order, which can consist of many items. Each item can be of a particular variant (think size, colour or brand). This gives us this as a rough database architecture:

API_DBA

One Order has many Items

One Item belongs to one Order

One Item has one Variant

One Variant can be in many Order Items

We could also think about an order having a purchaser and a recipient. It may be too complex for the initial version of this API, but just so you can optionally add this my basic logic is:

One Order belongs to one User

One User has many Orders

One Order can be dispatched to one Recipient

One Recipient can receive many Orders

In my case I’m going to create the following objects:

[table caption=”Orders” ]
Name, Description
ID, our unique identifier for this order.
order_ref, this is the customer reference for the order
recipient, this is going to be an array of recipient address data.
shipping_method, the shipping method to be used for this order
recipient_id, the FK to the recipients table so we know who to post the order to.
[/table]

[table caption=”Items” ]
Name, Description
ID, our unique identifier for this item.
item_ref, this is the customer reference for the item
quantity, number if this item to be sent
variant_id, the Foreign key used to find the variant information for the order
[/table]

[table caption=”Variants” ]
Name, Description
ID, our unique identifier for this item. Usually an SKU
size, size of the variant
brand, brand of the variant
type, type of variant, eg hoodie, t-shirt
colour, the colour of the garment
design, the design on the garment (if any)
[/table]

(just for reference, if the tutorial were to be expanded, the recipient’s table would be included too. This provides better data normalisation than just listing the recipient of an order inside the order table.)

[table caption=”Recipients” ]
Name, Description
ID, our unique identifier for this order.
name, name of the recipient for shipping
address_1, first line of their address
address_2, second line of their address
city, their town or city
region, the county or state
country_code, a 2 digit ISO standard country code for international orders
post_code, their post code
phone, their phone number which will be given to the shipping company
email, optionally their email address for marketing
[/table]

Migrations

Laravel uses a feature called Migrations to create database schemas. This is fantastic when you’re working with multiple developers as you can architect the database in flat files and “migrate” changes each time you pull down a new version of the code base. It also makes it easier than writing out all of the database tables in SQL or using a tool like MySQL Workbench to create them. We’re going to use the power of the migrations in Laravel to create our API table layout.

From the command line, lets create a migration for each table we’re going to use

php artisan make:migration create_table_orders
php artisan make:migration create_table_items
php artisan make:migration create_table_variants

You’ll have three new files created in your project folder in database/migrations. These files will be prefixed with a date time stamp, for example php artisan make:migration create_table_orders. You’ll also note that there are some preexiting migrations for users and password resets. You’re welcome to poke around these and see what they’re doing before moving on.

Lets start with the orders migration. Open it up in Atom so we can add information about our table into it. What you’ll be presented with is a class containing an up function and a down function, which equate to create and delete. When we run migrations it creates the table, if we reset it’ll delete the table in our database. Lets add our table elements:

class CreateTableOrders extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('orders', function (Blueprint $table) {
            // This is an auto incrementing primary key
            $table->increments('id');
            // This is a string or integer provided by the customer
            $table->string('order_ref');
            // This would link to our recipients table and be a foreign key, but we're not implementing it in our tutorial
            $table->integer('recipient_id');
            // This is a string indicating what shipping method we're going to use. Technically this should be split into it's own table for shipping methods, but for now it'll do.
            $table->string('shipping_method');
            // Timestamps are really useful for data monitoring. They let you see the created_at and updated_at times for the record.
            $table->timestamps();
        });
    }

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

Our items table:

class CreateTableItems extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            // This is an auto incrementing primary key
            $table->increments('id');
            // This is a string or integer provided by the customer
            $table->string('item_ref');
            // How many of this item are in this order?
            $table->integer('quantity');
            // This is a Forigin Key to the variants table, allowing us to know which of our item variants we want to provide in the order.
            $table->string('variant_id');
            // Timestamps are really useful for data monitoring. They let you see the created_at and updated_at times for the record.
            $table->timestamps();
        });
    }

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

And finally our Variants table:

class CreateTableVariants extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('variants', function (Blueprint $table) {
            // This is an auto incrementing primary key
            $table->increments('id');
            // OPTIONALLY:
            // an item can have an SKU. This is a unique id and is great for a primary key, but there are ongoing debates in the MySQL community over this being a good or bad idea. Auto incrementing fields are easier to index after all.
            //
            // If you wanted to include an SKU you could do it by using the following:
            //$table->string('sku')->unique();
            // This is the garment size
            $table->string('size');
            // This is the garment brand
            $table->string('brand');
            // This is the garment type
            $table->string('type');
            // This is the garment colour
            $table->string('colour');
            // This is the garment design
            $table->string('design');
            // Timestamps are really useful for data monitoring. They let you see the created_at and updated_at times for the record.
            $table->timestamps();
        });
    }

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

Now, before we can begin playing with migrations, you need to have your database connection setup. If you’re happy that it is then lets go back to the command line and run:

php artisan migrate

You should get a message similar to the following in response:

Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2016_03_06_174944_create_table_items
Migrated: 2016_03_06_174944_create_table_orders
Migrated: 2016_03_06_174945_create_table_variants

If you got anything else, including an error, then you need to take a look at what it’s telling you and correct it before continuing.

Optionally at this point you can open up a database editor and check it’s all there as you expected it to be. Since I’m calling this another milestone in the project, I’m also going to commit my changes.

git add -A
git commit -m "initial database migrations created"

The migration tool is quite powerful and will let you roll back migrations, or even reset them (delete the tables – remember those down functions in our migration files – that’s when these are called) or refresh, which resets then re-migrates the tables. Take a look at the Laravel docs on migrations for more information.

Seeders

A quick note on seeders. We can actually create a few records in the database using a seeder in Laravel, which is great for testing things like API get requests. Seeders are created on the command line using php artisan make:seeder. It might be worth adding some for our tables, but right now I won’t. You can always research if you’re interested in the subject.

Creating our Models

Now that the database has been created, we can begin to look at making some API calls to retrieve, add, delete and edit data to them. Most of our work will take place in the App folder form now on.

In order to talk to the database in Laravel we will be using a model. Once again, if you want details of MVC frameworks in general, or what models do in Laravel I encourage you to do your own research. I can’t cover everything here! What we will do is drop back to the command line and create some models for our new tables. I follow the convention of models being named as plural – so “order” is “orders”. This is preference and you don’t need to follow it if you don’t want to.

php artisan make:model Orders
# Model created successfully.
php artisan make:model Items
# Model created successfully.
php artisan make:model Variants
# Model created successfully.

You’ll see the app directory has files named the same as those listed on the command line arguments.Laravel uses Eloquent to mange database queries and relationships. Lets open them up one at a time and define some of these relationships between the tables.

The orders table needs to be related to items. Since one order has many items, we can reflect it in Laravel’s order model like so:

class Orders extends Model
{
    public function items()
    {
        return $this->hasMany('App\Items');
    }
}

Similarly we need to create the reverse of the relationship in the items model:

class Items extends Model
{

    public function order()
    {
        return $this->belongsTo('App\Orders');
    }

}

But, an item can also have a variant, so lets add another relationship to the same items model:

class Items extends Model
{

    public function order()
    {
        return $this->belongsTo('App\Orders');
    }

    public function variant()
    {
        return $this->belongsTo('App\Variants');
    }

}

Take note, that because there’s one variant, and one order for one item, I’ve used singulars as the function names. On the orders model I’ve used a plural “items” as there are many items in an order. This is preference, and adjust as you see fit.

Finally lets load up the variants model and add the items relationship:

class Variants extends Model
{
    public function items()
    {
        return $this->hasMany('App\Items');
    }
}

We’ll see how these relationships benefit us later. For now, lets take a look at further work on the models. A model will use a table of the same name by default, find out more at the Laravel docs website.

I’m also going to allow fillable fields using mass assignment. To do this in each of the models create an array of variables that you’ll allow to be fillable.

The orders class now looks like this:

class Orders extends Model
{
    protected $fillable = ['order_ref', 'recipient_id', 'shipping_method'];
    
    public function items()
    {
        return $this->hasMany('App\Items');
    }
}

Lets add fillable column names to the other models.

Items:

protected $fillable = ['item_ref', 'quantity', 'variant_id'];

Variants:

protected $fillable = ['size', 'brand', 'colour', 'type', 'design'];

That’s us done playing with models right now. Save all that and lets add it to git.

git add -A 
git commit -m "created models for orders, items and variants with fillable fields defined and relationships created"

Filed Under: Development, Laravel, Technology Tagged With: API, Databases, Dingo API, Getting started with Laravel 5 & Dingo API, Laravel, Laravel Migrations, larvel 5

Getting started with Laravel 5 & Dingo API: 1. Setting up the environment

2016/03/10 by sudo

In this series, I’m going to be writing about the creation of an API with Laravel 5.2 and Dingo API. The tutorial will focus around a fictional company that receives orders for garments from a number of 3rd party suppliers. 3rd parties place orders for items via the API, which then get dispatched to a recipient.

Setting Up a New Environment

So, the first thing to do is create a new environment for development. I’ll be using a Linux operating system to do development without using Laravel’s Homestead. You can of course use Homestead if that’s your preferred development method, but I can’t stand virtual machines eating system resources.

Installing pre-requisites

First off, you need to get the latest viable version of PHP and git for your OS. I’m using a Linux Mint 17.2, so I’ll be using apt-get.

sudo apt-get install php5-cli git mysql-server mysql-client

MySQL

MySQL will need to be configured. Set a memorable but secure root password. You can optionally create a limited user account (highly recommended), but since this is a local development environment I’ll just be using root credentials to allow it access to the database.

Create a database for the project. I’m calling mine “api” in order to remain as simple as possible.

Install Composer

I don’t intend to cover the installation of composer here, but you can find out up to date information from their website getcomposer.org. This is required to complete the rest of the guide.

Install Laravel

You should be able to install Laravel globally using composer:

composer global require "laravel/installer"

If you have any problems I’d suggest going to the Laravel website and checking for up to date installation instructions.

Recommended Tools

Just quickly, I use either Sublime text (paid for) or Atom (free and open source) for development. I’ll be focusing on Atom as it’s more accessible due to it’s open source development. Atom is great out of the box, but take a look at plugins to make it far more powerful as a development tool.

It’s also worth downloading Postman from the Chrome app store, unless you’re a curl lover it just makes things easier later.

Setting up the Project

Open up a new terminal and create a new Laravel application called api:

laravel new api

You’ll get some output about crafting a new application, just let it do it’s thing. Once finished and dropped back to the command prompt, go into the new directory and launch Atom in the current directory.

cd api
atom .

Now, probably the first thing we want to do is get some version control going on in case we screw up. Let’s create a new git repository here, and commit the current files.

git init
git add -A
git commit -m "initial laravel setup"

Next, lets grab Dingo API, which we’ll be using in the project to perform our REST requests.

composer require dingo/api:1.0.x@dev

Composer will go and do the heavy lifting, grabbing dependencies and setting up dingo for us.

We now want to make some changes to the config in Laravel, so using Atom open “config/app.php” and add a line to the bottom of the service providers array.

'providers' => [
    // ... leave other lines intact, just add the below...
    // Add a provider for Dingo API
    Dingo\Api\Provider\LaravelServiceProvider::class
],

Now lets run vendor publish to get the api config file setup.

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"

Great, so we have laravel and dingo installed. Lets just run through some configuration settings for dingo. Open up “config/api.php”. Hopefully this file has enough comments in it that you’ll understand what you need to change for your implementation. For this guide I’m simply going to edit a few variables to have an API prefix and enable debugging:

'prefix' => env('API_PREFIX', 'api'),

'debug' => env('API_DEBUG', true),

One more thing we need to do. Earlier you created a database called “api” and hopefully a user with a password who has permissions over that database. If not do that now. Then, open up the .env file in the Laravel installation and enter the details in the under the DB_ section:

DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=api
DB_USERNAME=user
DB_PASSWORD=secret

This will be used for MySQL connections later.

Okay, we’ve reached a good point to commit our changes to git

git add -A
git commit -m "setup dingo API"

That’s basically it for setup, lets start crafting an API!

The Beginnings: First API Hook

Lets jump straight into Atom and load the “routes.php” file. At the very bottom of the file, lets add in a call to the Dingo API Router.

$api = app('Dingo\Api\Routing\Router');

$api->version('v1', function ($api) {
    $api->get('/', function() {
        return ['test' => true];
    });
});

Now if you save the file and run the application – I’ll use PHP to serve it locally – you’ll be able to visit the page to get the response.

php artisan serve
#Laravel development server started on http://localhost:8000/

now go to http://localhost:8000/api/ in your web browser, or better yet using postman and you should see the response:

{"test":true}

Great, so what have we done here? Well first, we’ve created a new route for the v1 API. At the moment it’s just using the base URL “/api/” but we will change that later. We’ve specified that we will respond to a get request for a “v1” API request and return an array, which Dingo was nice enough to turn into JSON. This isn’t very useful yet, so next time we will start looking at how to do more interesting things.

Filed Under: Development, Laravel, Technology Tagged With: API, Dingo API, Getting started with Laravel 5 & Dingo API, Laravel, larvel 5, PHP development

Recent Posts

  • Disable iLO on HP Microserver Gen8
  • Ubuntu Desktop 24.04 Change Wallpaper Settings
  • Customising Ubuntu Desktop 24.04
  • Remove domains from Let’s Encrypt using Certbot
  • Install Jetbrains Toolbox on Ubuntu 22.04

Tags

API auditing crochet data recovery debian debudding development Dingo API docker email Getting started with Laravel 5 & Dingo API hard drive health HP Microserver KVM Laravel larvel 5 lenovo Linux Minion mint netgear nas networking network shares php PHP development Postfix raspberry pi review samba security SMART smartctl smartmontools smb testing traefik ubuntu ubuntu 18.04 ubuntu 20.04 ubuntu 22.04 ubuntu server vagrant Virtual machines xdebug xubuntu

© Copyright 2015 apt get life

 

Loading Comments...