2017 © Pedro Peláez
 

library api

RESTful HTTP API dev tool for Laravel or Lumen based project

image

appkr/api

RESTful HTTP API dev tool for Laravel or Lumen based project

  • Thursday, September 28, 2017
  • by appkr
  • Repository
  • 4 Watchers
  • 28 Stars
  • 5,694 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 4 Forks
  • 0 Open issues
  • 27 Versions
  • 12 % Grown

The README.md

RESTful HTTP API component for Laravel or Lumen based project

Latest Stable Version Total Downloads Latest Unstable Version License, (*1)

한국어 매뉴얼, (*2)

INDEX


, (*3)

1. ABOUT

A lightweight RESTful API builder for Laravel or/and Lumen project., (*4)

, (*5)

2. FEATURE

  1. Provides Laravel/Lumen Service Provider for the league/fractal.
  2. Provides configuration capability for the library.
  3. Provides easy way of making transformed/serialized API response.
  4. Provides make:transformer artisan command.
  5. Provides examples, so that users can quickly copy & paste into his/her project.

, (*6)

3. LARAVEL/LUMEN IMPLEMENTATION EXAMPLE(How to use)

3.1. API Endpoint

Define RESTful resource route in Laravel way., (*7)

<?php // app/Http/routes.php OR routes/web.php OR routes/api.php

Route::group(['prefix' => 'v1'], function () {
    Route::resource(
        'books',
        'BooksController',
        ['except' => ['create', 'edit']]
    );
});

Lumen doesn't support RESTful resource route. You have to define them one by one., (*8)

<?php // app/Http/routes.php OR routes/web.php OR routes/api.php

$app->group(['prefix' => 'v1'], function ($app) {
    $app->get('books', [
        'as'   => 'v1.books.index',
        'uses' => 'BooksController@index',
    ]);
    $app->get('books/{id}', [
        'as'   => 'v1.books.show',
        'uses' => 'BooksController@show',
    ]);
    $app->post('books', [
        'as'   => 'v1.books.store',
        'uses' => 'BooksController@store',
    ]);
    $app->put('books/{id}, [
       'as'   => 'v1.books.update',
       'uses' => 'BooksController@update',
   ]);
    $app->delete('books/{id}', [
       'as'   => 'v1.books.destroy',
       'uses' => 'BooksController@destroy',
   ]);
});

3.2. Controller

The subsequent code block is the controller logic for /v1/books/{id} endpoint. Note the use cases of json() helper and transformer on the following code block., (*9)

<?php // app/Http/Controllers/BooksController.php

namespace App\Http\Controllers\V1;

use App\Http\Controllers\Controller;
use App\Book;
use App\Transformers\BookTransformer;
use Illuminate\Http\Request;

class BooksController extends Controller
{
    public function index()
    {
        return json()->withPagination(
            Book::latest()->paginate(5),
            new BookTransformer
        );
    }

    public function store(Request $request)
    {
        // Assumes that validation is done at somewhere else
        return json()->created(
            $request->user()->create($request->all())
        );
    }

    public function show($id)
    {
        return json()->withItem(
            Book::findOrFail($id),
            new BookTransformer
        );
    }

    public function update(Request $request, $id)
    {
        $book = Book::findOrFail($id);

        return ($book->update($request->all()))
            ? json()->success('Updated')
            : json()->error('Failed to update');
    }

    public function destroy($id)
    {
        $book = Book::findOrFail($id);

        return ($book->delete())
            ? json()->success('Deleted')
            : json()->error('Failed to delete');
    }
}

, (*10)

4. HOW TO INSTALL

4.1. Composer.

$ composer require "appkr/api: 1.*"

4.2. Add the service provider.

<?php // config/app.php (Laravel)

'providers' => [
    Appkr\Api\ApiServiceProvider::class,
];
<?php // boostrap/app.php (Lumen)

$app->register(Appkr\Api\ApiServiceProvider::class);

4.3. [OPTIONAL] Publish assets.

# Laravel only
$ php artisan vendor:publish --provider="Appkr\Api\ApiServiceProvider"

The configuration file is located at config/api.php., (*11)

In Lumen we can manually create config/api.php file, and then activate the configuration at bootstrap/app.php like the following., (*12)

<?php // bootstrap/app.php (Lumen)

$app->register(Appkr\Api\ApiServiceProvider::class);
$app->configure('api');

Done !, (*13)

, (*14)

5. CONFIG

Skim through the config/api.php, which is inline documented., (*15)

, (*16)

6. TRANSFORMER

6.1. What?

For more about what the transformer is, what you can do with this, and why it is required, see this page. 1 transformer for 1 model is a best practice(e.g. BookTransformer for Book model)., (*17)

6.2. Transformer Boilerplate Generator

Luckily this package ships with an artisan command that conveniently generates a transformer class., (*18)

$ php artisan make:transformer {subject} {--includes=}
# e.g. php artisan make:transformer "App\Book" --includes="App\\User:author,App\\Comment:comments:true"
  • subject_ The string name of the model class., (*19)

  • includes_ Sub-resources that is related to the subject model. By providing this option, your API client can have control over the response body. see NESTING SUB RESOURCES section., (*20)

    The option's signature is --include=Model,eloquent_relationship_methods[,isCollection]., (*21)

    If the include-able sub-resource is a type of collection, like Book and Comment relationship in the example, we provide true as the third value of the option., (*22)

Note, (*23)

We should always use double back slashes (\\), when passing a namespace in artisan command WITHOUT quotation marks., (*24)

$ php artisan make:transformer App\\Book --includes=App\\User:author,App\\Comment:comments:true
  

A generated file will look like this:, (*25)

<?php // app/Transformers/BookTransformer.php

namespace App\Transformers;

use App\Book;
use Appkr\Api\TransformerAbstract;
use League\Fractal;
use League\Fractal\ParamBag;

class BookTransformer extends TransformerAbstract
{
    /**
     * List of resources possible to include using url query string.
     *
     * @var  array
     */
    protected $availableIncludes = [
        'author',
        'comments'
    ];

    /**
     * Transform single resource.
     *
     * @param  \App\Book $book
     * @return  array
     */
    public function transform(Book $book)
    {
        $payload = [
            'id' => (int) $book->id,
            // ...
            'created' => $book->created_at->toIso8601String(),
            'link' => [
                 'rel' => 'self',
                 'href' => route('api.v1.books.show', $book->id),
            ],
        ];

        return $this->buildPayload($payload);
    }

    /**
     * Include author.
     * This method is used, when an API client request /v1/books?include=author
     *
     * @param  \App\Book $book
     * @param \League\Fractal\ParamBag|null $params
     * @return  \League\Fractal\Resource\Item
     */
    public function includeAuthor(Book $book, ParamBag $params = null)
    {
        return $this->item(
            $book->author,
            new \App\Transformers\UserTransformer($params)
        );
    }

    /**
     * Include comments.
     * This method is used, when an API client request /v1/books??include=comments
     *
     * @param  \App\Book $book
     * @param  \League\Fractal\ParamBag|null $params
     * @return  \League\Fractal\Resource\Collection
     */
    public function includeComments(Book $book, ParamBag $params = null)
    {
        $transformer = new \App\Transformers\CommentTransformer($params);

        $comments = $book->comments()
            ->limit($transformer->getLimit())
            ->offset($transformer->getOffset())
            ->orderBy($transformer->getSortKey(), $transformer->getSortDirection())
            ->get();

        return $this->collection($comments, $transformer);
    }
}

, (*26)

7. NESTING SUB-RESOURCES

An API client can request a resource with its sub-resource. The following example is requesting authors list. At the same time, it requests each author's books list. It also has additional parameters, which reads as 'I need total of 3 books for this author when ordered by recency without any skipping'., (*27)

GET /authors?include=books:limit(3|0):sort(id|desc)

When including multiple sub resources,, (*28)

GET /authors?include[]=books:limit(2|0)&include[]=comments:sort(id|asc)

# or alternatively

GET /authors?include=books:limit(2|0),comments:sort(id|asc)

In case of deep recursive nesting, use dot (.). In the following example, we assume the publisher model has relationship with somethingelse model., (*29)

GET /books?include=author,publisher.somethingelse

, (*30)

8. APIs

The following is the full list of response methods that Appkr\Api\Http\Response provides. Really handy when making a json response in a controller., (*31)

8.1. Appkr\Api\Response - Available Methods

<?php

// Generic response.
// If valid callback parameter is provided, jsonp response can be provided.
// This is a very base method. All other responses are utilizing this.
respond(array $payload);

// Respond collection of resources
// If $transformer is not given as the second argument,
// this class does its best to transform the payload to a simple array
withCollection(
    \Illuminate\Database\Eloquent\Collection $collection,
    \League\Fractal\TransformerAbstract|null $transformer,
    string|null $resourceKey // for JsonApiSerializer only
);

// Respond single item
withItem(
    \Illuminate\Database\Eloquent\Model $model,
    \League\Fractal\TransformerAbstract|null $transformer,
    string|null $resourceKey // for JsonApiSerializer only
);

// Respond collection of resources with pagination
withPagination(
    \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator,
    \League\Fractal\TransformerAbstract|null $transformer,
    string|null $resourceKey // for JsonApiSerializer only
);

// Respond json formatted success message
// api.php provides configuration capability
success(string|array $message);

// Respond 201
// If an Eloquent model is given at an argument,
// the class tries its best to transform the model to a simple array
created(string|array|\Illuminate\Database\Eloquent\Model $primitive);

// Respond 204
noContent();

// Respond 304
notModified();

// Generic error response
// This is another base method. Every other error responses use this.
// If an instance of \Exception is given as an argument,
// this class does its best to properly format a message and status code
error(string|array|\Exception|null $message);

// Respond 401
// Note that this actually means unauthenticated
unauthorizedError(string|array|null $message);

// Respond 403
// Note that this actually means unauthorized
forbiddenError(string|array|null $message);

// Respond 404
notFoundError(string|array|null $message);

// Respond 405
notAllowedError(string|array|null $message);

// Respond 406
notAcceptableError(string|array|null $message);

// Respond 409
conflictError(string|array|null $message);

// Respond 410
goneError(string|array|null $message);

// Respond 422
unprocessableError(string|array|null $message);

// Respond 500
internalError(string|array|null $message);

// Set http status code
// This method is chain-able
setStatusCode(int $statusCode);

// Set http response header
// This method is chain-able
setHeaders(array $headers);

// Set additional meta data
// This method is chain-able
setMeta(array $meta);

8.2. Appkr\Api\TransformerAbstract - Available Methods

<?php

// We can apply this method against an instantiated transformer,
// to get the parsed query parameters that belongs only to the current resource.
//
// e.g. GET /v1/author?include[]=books:limit(2|0)&include[]=comments:sort(id|asc)
//      $transformer = new BookTransformer;
//      $transformer->get();
// Will produce all parsed parameters:
//      // [
//      //     'limit'  => 2 // if not given default value at config
//      //     'offset' => 0 // if not given default value at config
//      //     'sort'   => 'created_at' // if given, given value
//      //     'order'  => 'desc' // if given, given value
//      // ]
// Alternatively we can pass a key.
//      $transformer->get('limit');
// Will produce limit parameter:
//      // 2
get(string|null $key)

// Exactly does the same function as get.
// Was laid here, to enhance readability.
getParsedParams(string|null $key)

8.3. helpers.php - Available Functions

<?php

// Make JSON response
// Returns Appkr\Api\Http\Response object if no argument is given,
// from there you can chain any public apis that are listed above.
json(array|null $payload)

// Determine if the current framework is Laravel
is_laravel();

// Determine if the current framework is Lumen
is_lumen();

// Determine if the current request is for API endpoints, and expecting API response
is_api_request();

// Determine if the request is for update
is_update_request();

// Determine if the request is for delete
is_delete_request();

, (*32)

9. BUNDLED EXAMPLE

The package is bundled with a set of example that follows the best practices. It includes:, (*33)

  • Database migrations and seeder
  • routes definition, Eloquent Model and corresponding Controller
  • FormRequest (Laravel only)
  • Transformer
  • Integration Test

Follow the guide to activate and test the example., (*34)

9.1. Activate examples

Uncomment the line., (*35)

<?php // vendor/appkr/api/src/ApiServiceProvider.php

$this->publishExamples();

9.2. Migrate and seed tables

Do the following to make test table and seed test data. Highly recommend to use SQLite, to avoid polluting the main database of yours., (*36)

$ php artisan migrate --path="vendor/appkr/api/src/example/database/migrations" --database="sqlite"
$ php artisan db:seed --class="Appkr\Api\Example\DatabaseSeeder" --database="sqlite"

9.3. See it works

Boot up a server., (*37)

$ php artisan serve

Head on to GET /v1/books, and you should see a well formatted json response. Try each route to get accustomed to, such as /v1/books=include=authors, /v1/authors=include=books:limit(2|0):order(id|desc)., (*38)

, (*39)

9.4. [OPTIONAL] Run integration test

# Laravel
$ vendor/bin/phpunit vendor/appkr/api/src/example/BookApiTestForLaravel.php
# Lumen
$ vendor/bin/phpunit vendor/appkr/api/src/example/BookApiTestForLumen.php

Note, (*40)

If you finished evaluating the example, don't forget to rollback the migration and re-comment the unnecessary lines at ApiServiceProvider., (*41)

10. LICENSE & CONTRIBUTION

MIT License. Issues and PRs are always welcomed., (*42)

11. CHANGELOG

v3.0.1

  • Supports auto package discovery in Laravel 5.5 (No need to add ServiceProvider in config/app.php)

v3.0.0

  • API not changed.
  • Update league/fractal version to 0.16.0

v2.3.4

  • jsonEncodeOption config added.

v2.3.3

  • Appkr\Api\Http\UnexpectedIncludesParamException will be thrown instead of UnexpectedValueException when includes query params are not valid.

v2.3.0

  • withCollection() now accepts Illuminate\Support\Collection.
  • Fix bug at SimpleArrayTransformer.

v2.2.0

  • Field name converting to snake or camel case depending on configuration (config('api.convert.key')).
  • Date format converting depending on configuration (config('api.convert.date')).

v2.1.0

  • TransformerAbstract::buildPayload method added to filter the list of response fields (Backward compatible).
  • Artisan generated transformer template changed (Backward compatible).

v2.0.0

  • TransformerAbstract's API changed.
  • Partial response by query string feature removed. Instead we can explicitly set the list of attributes to respond in a Transformer's $visible or $hidden property.

v1.1.0 [buggy]

  • Field grouping feature added for partial response conveniences.
  • TransformerAbstract now throws UnexpectedValueException instead of Exception, when params or values passed by API client are not acceptable.

12. SPONSORS

  • Thanks JetBrains for supporting phpStorm IDE.

, (*43)

The Versions

28/09 2017

dev-master

9999999-dev

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

28/09 2017

v3.0.3

3.0.3.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

03/09 2017

v3.0.2

3.0.2.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

04/07 2017

v3.0.1

3.0.1.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

07/05 2017

v3.0.0

3.0.0.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

09/01 2017

v2.3.4

2.3.4.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

09/01 2017

v2.3.3

2.3.3.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

30/12 2016

v2.3.2

2.3.2.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

30/12 2016

v2.3.1

2.3.1.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

22/12 2016

v2.3.0

2.3.0.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

21/12 2016

v2.2.0

2.2.0.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

19/12 2016

v2.1.0

2.1.0.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

16/12 2016

v2.0.0

2.0.0.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

09/12 2016

v1.0.2

1.0.2.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

23/04 2016

v1.0.1

1.0.1.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal restful api

30/03 2016

v1.0.0

1.0.0.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

20/01 2016

0.1.10

0.1.10.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

18/01 2016

0.1.9

0.1.9.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

18/01 2016

0.1.8

0.1.8.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

18/01 2016

0.1.6

0.1.6.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

18/01 2016

0.1.7

0.1.7.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

18/01 2016

0.1.5

0.1.5.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

17/01 2016

0.1.4

0.1.4.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

15/01 2016

0.1.3

0.1.3.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

12/01 2016

0.1.2

0.1.2.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

04/01 2016

0.1.1

0.1.1.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal

04/01 2016

0.1.0

0.1.0.0

RESTful HTTP API dev tool for Laravel or Lumen based project

  Sources   Download

MIT

The Requires

 

The Development Requires

by Avatar appkr

laravel fractal