• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

nilportugues/laravel5-jsonapi: Laravel 5 JSON API Transformer Package

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称(OpenSource Name):

nilportugues/laravel5-jsonapi

开源软件地址(OpenSource Url):

https://github.com/nilportugues/laravel5-jsonapi

开源编程语言(OpenSource Language):

PHP 100.0%

开源软件介绍(OpenSource Introduction):

Laravel 5 JSON API Server Package

Scrutinizer Code Quality SensioLabsInsight Latest Stable Version Total Downloads License Donate

Compatible with Laravel 5.0, 5.1 & 5.2

  • Package provides a full implementation of the JSON API specification, and is featured on the official site!
  • A JSON API Transformer that will allow you to convert any mapped object into a valid JSON API resource.
  • Controller boilerplate to write a fully compiliant JSON API Server using your exisiting Eloquent Models.
  • Works for Laravel 5 and Lumen frameworks.

Installation

Use Composer to install the package:

composer require nilportugues/laravel5-json-api

Now run the following artisan command:

php artisan vendor:publish

Configuration (Laravel 5 & Lumen)

For the sake of having a real life example, this configuration will guide you on how to set up 7 end-points for two resources, Employees and Orders.

Both Employees and Orders resources will be Eloquent models, being related one with the other.

Furthermore, Employeeswill be using an Eloquent feature, appended fields to demonstrate how it is possible to make the most of Eloquent and this package all together.

Configuration for Laravel 5

Step 1: Add the Service Provider

Open up config/app.php and add the following line under providers array:

'providers' => [
    //...
    NilPortugues\Laravel5\JsonApi\Laravel5JsonApiServiceProvider::class,
],

Step 2: Defining routes

We will be planning the resources ahead its implementation. All routes require to have a name.

This is how our app/Http/routes.php will look:

<?php
Route::group(['namespace' => 'Api'], function() {
    Route::resource('employees', 'EmployeesController');    
    Route::get(
        'employees/{employee_id}/orders', [
        'as' => 'employees.orders',
        'uses' => 'EmployeesController@getOrdersByEmployee'
    ]);
});
//...

Step 3: Definition

First, let's define the Models for Employees and Orders using Eloquent.

Employees (Eloquent Model)

<?php namespace App\Model\Database;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Validation\ValidatesRequests;

class Employees extends Model
{
    public $timestamps = false;
    protected $table = 'employees';    
    protected $primaryKey = 'id';
    protected $appends = ['full_name'];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function latestOrders()
    {
        return $this->hasMany(Orders::class, 'employee_id')->limit(10);
    }

    /**
     * @return string
     */
    public function getFullNameAttribute()
    {
        return $this->first_name.' '.$this->last_name;
    }
}

Employees SQL

CREATE TABLE `employees` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `company` varchar(50) DEFAULT NULL,
  `last_name` varchar(50) DEFAULT NULL,
  `first_name` varchar(50) DEFAULT NULL,
  `email_address` varchar(50) DEFAULT NULL,
  `job_title` varchar(50) DEFAULT NULL,
  `business_phone` varchar(25) DEFAULT NULL,
  `home_phone` varchar(25) DEFAULT NULL,
  `mobile_phone` varchar(25) DEFAULT NULL,
  `fax_number` varchar(25) DEFAULT NULL,
  `address` longtext,
  `city` varchar(50) DEFAULT NULL,
  `state_province` varchar(50) DEFAULT NULL,
  `zip_postal_code` varchar(15) DEFAULT NULL,
  `country_region` varchar(50) DEFAULT NULL,
  `web_page` longtext,
  `notes` longtext,
  `attachments` longblob,
  PRIMARY KEY (`id`),
  KEY `city` (`city`),
  KEY `company` (`company`),
  KEY `first_name` (`first_name`),
  KEY `last_name` (`last_name`),
  KEY `zip_postal_code` (`zip_postal_code`),
  KEY `state_province` (`state_province`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
INSERT INTO `employees` (`id`, `company`, `last_name`, `first_name`, `email_address`, `job_title`, `business_phone`, `home_phone`, `mobile_phone`, `fax_number`, `address`, `city`, `state_province`, `zip_postal_code`, `country_region`, `web_page`, `notes`, `attachments`)
VALUES
    (10, 'Acme Industries', 'Smith', 'Mike', '[email protected]', 'Horticultarlist', '0118 9843212', NULL, NULL, NULL, '343 Friary Road', 'Manchester', 'Lancs.', 'M3 3DL', 'United Kingdom', NULL, NULL, NULL);

Orders (Eloquent Model)

<?php namespace App\Model\Database;

use Illuminate\Database\Eloquent\Model;

class Orders extends Model
{   
    public $timestamps = false;
    protected $table = 'orders';
    protected $primaryKey = 'id';

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function employee()
    {
        return $this->belongsTo(Employees::class, 'employee_id');
    }
}

Orders SQL

CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `employee_id` int(11) DEFAULT NULL,
  `customer_id` int(11) DEFAULT NULL,
  `order_date` datetime DEFAULT NULL,
  `shipped_date` datetime DEFAULT NULL,
  `shipper_id` int(11) DEFAULT NULL,
  `ship_name` varchar(50) DEFAULT NULL,
  `ship_address` longtext,
  `ship_city` varchar(50) DEFAULT NULL,
  `ship_state_province` varchar(50) DEFAULT NULL,
  `ship_zip_postal_code` varchar(50) DEFAULT NULL,
  `ship_country_region` varchar(50) DEFAULT NULL,
  `shipping_fee` decimal(19,4) DEFAULT '0.0000',
  `taxes` decimal(19,4) DEFAULT '0.0000',
  `payment_type` varchar(50) DEFAULT NULL,
  `paid_date` datetime DEFAULT NULL,
  `notes` longtext,
  `tax_rate` double DEFAULT '0',
  `tax_status_id` tinyint(4) DEFAULT NULL,
  `status_id` tinyint(4) DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `customer_id` (`customer_id`),
  KEY `employee_id` (`employee_id`),
  KEY `id` (`id`),
  KEY `shipper_id` (`shipper_id`),
  KEY `tax_status` (`tax_status_id`),
  KEY `ship_zip_postal_code` (`ship_zip_postal_code`),
  KEY `fk_orders_orders_status1` (`status_id`),  
  CONSTRAINT `fk_orders_employees1` FOREIGN KEY (`employee_id`) REFERENCES `employees` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=82 DEFAULT CHARSET=utf8;
INSERT INTO `orders` (`id`, `employee_id`, `customer_id`, `order_date`, `shipped_date`, `shipper_id`, `ship_name`, `ship_address`, `ship_city`, `ship_state_province`, `ship_zip_postal_code`, `ship_country_region`, `shipping_fee`, `taxes`, `payment_type`, `paid_date`, `notes`, `tax_rate`, `tax_status_id`, `status_id`)
VALUES
    (82, 10, NULL, '2015-03-12 00:00:00', '2015-03-12 00:00:00', NULL, NULL, '43, Borrowed Drive', 'New Oreleans', 'Louisiana', '4322', 'USA', 1.4000, 0.0000, NULL, NULL, NULL, 0, NULL, 0);

Follow up, we'll be creating Transformers. One Transformer is required for each class and it must implement the \NilPortugues\Api\Mappings\JsonApiMapping interface.

We will be placing these files at app/Model/Api:

EmployeesTransformer

<?php namespace App\Model\Api;

use App\Model\Database\Employees;
use NilPortugues\Api\Mappings\JsonApiMapping;

class EmployeesTransformer implements JsonApiMapping
{
    /**
     * Returns a string with the full class name, including namespace.
     *
     * @return string
     */
    public function getClass()
    {
        return Employees::class;
    }

    /**
     * Returns a string representing the resource name 
     * as it will be shown after the mapping.
     *
     * @return string
     */
    public function getAlias()
    {
        return 'employee';
    }

    /**
     * Returns an array of properties that will be renamed.
     * Key is current property from the class. 
     * Value is the property's alias name.
     *
     * @return array
     */
    public function getAliasedProperties()
    {
        return [
            'last_name' => 'surname',
            
        ];
    }

    /**
     * List of properties in the class that will be  ignored by the mapping.
     *
     * @return array
     */
    public function getHideProperties()
    {
        return [
            'attachments'
        ];
    }

    /**
     * Returns an array of properties that are used as an ID value.
     *
     * @return array
     */
    public function getIdProperties()
    {
        return ['id'];
    }

    /**
     * Returns a list of URLs. This urls must have placeholders 
     * to be replaced with the getIdProperties() values.
     *
     * @return array
     */
    public function getUrls()
    {
        return [
            'self' => ['name' => 'employees.show', 'as_id' => 'id'],
            'employees' => ['name' => 'employees.index'],
            'employee_orders' => ['name' => 'employees.orders', 'as_id' => 'id']
        ];
    }

    /**
     * Returns an array containing the relationship mappings as an array.
     * Key for each relationship defined must match a property of the mapped class.
     *
     * @return array
     */
    public function getRelationships()
    {
        return [];
    }
} 

Same goes for Orders, these files will also be placed at app/Model/Api:

OrdersTransformer

<?php namespace App\Model\Api;

use App\Model\Database\Orders;
use NilPortugues\Api\Mappings\JsonApiMapping;

class OrdersTransformer implements JsonApiMapping
{
    /**
     * {@inheritDoc}
     */
    public function getClass()
    {
        return Orders::class;
    }
    /**
     * {@inheritDoc}
     */
    public function getAlias()
    {
        return 'order';
    }
    /**
     * {@inheritDoc}
     */
    public function getAliasedProperties()
    {
        return [];
    }
    /**
     * {@inheritDoc}
     */
    public function getHideProperties()
    {
        return [];
    }
    /**
     * {@inheritDoc}
     */
    public function getIdProperties()
    {
        return ['id'];
    }
    /**
     * {@inheritDoc}
     */
    public function getUrls()
    {
        return [
            'self'     => ['name' => 'orders.show', 'as_id' => 'id'],
            'employee' => ['name' => 'employees.show', 'as_id' => 'employee_id'],
        ];
    }
    /**
     * {@inheritDoc}
     */
    public function getRelationships()
    {
        return [];
    }
    
    /**
     * List the fields that are mandatory in a persitence action (POST/PUT). 
     * If empty array is returned, all fields are mandatory.
     */
    public function getRequiredProperties()
    {
        return [];
    }    
} 

Step 4: Usage

Create file config/jsonapi.php. This file should return an array returning all the class mappings.

<?php
use App\Model\Api\EmployeesTransformer;
use App\Model\Api\OrdersTransformer;

return [
    EmployeesTransformer::class,
    OrdersTransformer::class,
];

Configuration for Lumen

Step 1: Add the Service Provider

Open up bootstrap/app.phpand add the following lines before the return $app; statement:

$app->register(\NilPortugues\Laravel5\JsonApi\Laravel5JsonApiServiceProvider::class);
$app->configure('jsonapi');

Also, enable Facades by uncommenting:

$app->withFacades();

Step 2: Defining routes

We will be planning the resources ahead its implementation. All routes require to have a name.

This is how our app/Http/routes.php will look:

<?php
$app->group(
    ['namespace' => 'Api'], function($app) {
        $app->get(
            'employees', [
            'as' => 'employees.index',
            'uses' =>'EmployeesController@index'
        ]);
        $app->post(
            'employees', [
            'as' => 'employees.store',
            'uses' =>'EmployeesController@store'
        ]);
        $app->get(
            'employees/{employee_id}', [
            'as' => 'employees.show', 
            'uses' =>'EmployeesController@show'
        ]);
        $app->put(
            'employees/{employee_id}', [
            'as' => 'employees.update', 
            'uses' =>'EmployeesController@update'
        ]);
        $app->patch(
            'employees/{employee_id}', [
            'as' => 'employees.patch',
            'uses' =>'EmployeesController@update'
        ]);
        $app->delete(
            'employees/{employee_id}', [
            'as' => 'employees.destroy',
            'uses' =>'EmployeesController@destroy'
        ]);
        
        $app->get(
            'employees/{employee_id}/orders', [
            'as' => 'employees.orders', 
            'uses' => 'EmployeesController@getOrdersByEmployee'
        ]);
    }
);
//...

Step 3: Definition

Same as Laravel 5.

Step 4: Usage

Same as Laravel 5.

JsonApiController

Whether it's Laravel 5 or Lumen, usage is exactly the same.

Let's create a new controller that extends the JsonApiController provided by this package, as follows:

Lumen users must extends from LumenJsonApiController not JsonApiController.


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
GeneaLabs/laravel-model-caching: Eloquent model-caching made easy.发布时间:2022-07-07
下一篇:
arrilot/laravel-widgets: Widgets for Laravel发布时间:2022-07-07
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap