lujo/laravel-rest

Laravel包,用于创建简单的REST API

2.0.0 2023-09-14 10:30 UTC

This package is auto-updated.

Last update: 2024-09-14 12:34:27 UTC


README

Laravel包,用于创建简单的REST API。

安装

使用以下命令通过Composer安装此包:

composer require lujo/laravel-rest

或者你可以在composer.json中添加以下行

"require": {
    ...
    "lujo/laravel-rest": "*"
}

然后运行

composer install

描述

此Laravel包包含两个类:RestRouteRestController

  • RestRouteroute(...)函数中执行特定资源的所有路由操作。
  • RestController应该由其他控制器类扩展以用于特定资源。

用法

1. 创建Eloquent模型

为了使用此REST包,首先你必须为某些资源创建Eloquent模型。

示例:Article模型

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Article extends Model {

    protected $table = 'article';

    protected $fillable = [
        'title',
        'description',
        'content'
    ];

    // Optional realtions and other Eloquent stuff
    public function articleAuthor() {
        return $this->hasOne('App\Models\Author');
    }
}

2. 创建控制器

模型创建后,你可以创建一个简单的控制器类,并从该包扩展RestController类。你还必须实现函数getModel(),它必须返回在上一步骤中创建的Eloquent模型,这是你希望通过此REST API公开的资源。

示例控制器类

<?php

namespace App\Http\Controllers;

use Illuminate\Database\Eloquent\Model;
use App\Models\Article;
use Lujo\Laravel\Rest\RestController;


class ArticleController extends RestController {

    /**
     * @return Model
     */
    protected function getModel() {
        return new Article();
    }
    
    // Optional override, transforms every model before returning it from API.
    protected function beforeGet($model) {
        return $model;
    }
    
    // Optional override, transform received request before creating new model from it.
    protected function beforeCreate($request) {
        return $request->all();
    }
    
    // Optional override, transform received request before updating existing model from it.
    protected function beforeUpdate($request) {
        return $request->all();
    }
    
    // Optional override, perform some action on/with model before it is deleted.
    protected function beforeDelete($model) {
        return null;
    }
    
    // Optional override, specify list of relations to return on specific action
    protected function getWith($request, $action) {
        if($action === 'INDEX') {
            return ['text'];
        }
        return ['author', 'comments', 'text'];
    }
    
    // Optional override, specify list of where statements to return on specific action
    protected function getWhere($request, $action) {
        if($action === 'DELETE') {
            return [['name', 'Test']];
        }
        return [['status', 'ACTIVE'], ['enabled', true]];
    }
    
    // Optional override, specify additional where query statement in form of a anonymous function
    protected function getWhereFunction($request, $action) {
        return function($q) {
            $q->where('name', 'Test')->orWhere('status', 'ACTIVE');
        };
    }

    // Optional override, when INDEX method is called and this method returns true, the returend JSON will contain 
    // count data used for pagination e.g. {result_count: 10, total_count: 45, data: [...results]}
    protected function withCountMetadata($request) {
        return false;
    }
}

如果你不使用它们,所有可选的覆盖函数都不是必需的,可以从你的控制器类实现中安全地删除它们。

3. 创建路由

完成前两个步骤后,打开你的Laravel路由文件routes/web.php,并使用RestRoute类的静态函数route($router, $prefix, $controller, $include = null)创建路由结构。

示例routes/web.php路由

<?php 

use Laravel\Laravel\Routing\Router;
use Lujo\Laravel\Rest\RestRoute;

/**
 * @var $router Router
 */

// This will create all article routes ('INDEX', 'ONE', 'CREATE', 'UPDATE', 'DELETE') for routes /articles/*
RestRoute::route($router, 'articles', 'ArticleController', 'middleware1');

// This will create only 'INDEX' and 'ONE' for routes /users/*
RestRoute::route($router, 'users', 'UserController', ['middleware1', 'middleware2'], ['INDEX', 'ONE']);

// This will create only 'INDEX', 'CREATE' and 'UPDATE' routes for /example/* but apply middlewares only on CREATE and UPDATE
RestRoute::route($router, 'examples', 'ExampleController', ['CREATE' => ['middleware1', 'middleware2'], 'UPDATE' => 'middleware2'], 
        ['INDEX', 'CREATE', 'UPDATE']);

// This will create all routes and apply middleware1 and middleware2 to INDEX and ONE route, on others will middleware3 be applied.
RestRoute::route($router, 'users', 'UserController', ['INDEX,ONE' => ['middleware1', 'middleware2'], 'middleware3']);

// Example subgroup of routes (/article/authors/*) with middleware
$router->group(['prefix' => 'article', 'middleware' => 'middleware1'], function ($subRoute) {
        RestRoute::route($subRoute, 'authors', 'AuthorController');
    }
);

生成的REST资源路由格式如下

获取所有资源具有以下HTTP GET URL参数

  • skip - 要跳过的资源数量(例如,30)
  • limit - 要检索的资源数量(例如,15)
  • sort - 对返回资源进行排序的字段(例如,'first_name')
  • order - 返回资源的排序方式('asc'或'desc')

示例HTTP GET请求: http://site.com/api/resource?skip=30&limit=6&sort=resource_name&order=desc

响应

头部

Content-type: application/json
X-Total-Count: 10
X-Result-Count: 6

当方法withCountMetadata()返回false时的正文

[
    {"id": 31, "resource_name": "Resource name", "description": "Some resource description"}, 
    {"id": 32, "resource_name": "Resource name", "description": "Some resource description"},
    {"id": 33, "resource_name": "Resource name", "description": "Some resource description"}, 
    {"id": 34, "resource_name": "Resource name", "description": "Some resource description"}, 
    {"id": 35, "resource_name": "Resource name", "description": "Some resource description"},
    {"id": 36, "resource_name": "Resource name", "description": "Some resource description"}
]

当方法withCountMetadata()返回true时的正文

{
    total_count: 10,
    result_count: 6,
    data: [
        {"id": 31, "resource_name": "Resource name", "description": "Some resource description"}, 
        {"id": 32, "resource_name": "Resource name", "description": "Some resource description"},
        {"id": 33, "resource_name": "Resource name", "description": "Some resource description"}, 
        {"id": 34, "resource_name": "Resource name", "description": "Some resource description"}, 
        {"id": 35, "resource_name": "Resource name", "description": "Some resource description"},
        {"id": 36, "resource_name": "Resource name", "description": "Some resource description"}
    ]
}

授权

MIT