fadugyamfi/laravel-api-base

Laravel包,用于简化RESTful API开发

0.9.6 2024-06-02 16:22 UTC

README

Laravel包,用于简化RESTful API开发

关于

这个库通过提供基础控制器、请求、资源、模型以及您需要的所有CRUD功能,包括数据搜索和计数端点,可以帮助您显著提高使用Laravel开发RESTful API的速度。

安装

推荐通过[Packagist][]和[Composer][]安装。运行以下命令安装包并将它添加到项目的composer.json中。

composer require fadugyamfi/laravel-api-base

最新版本的Laravel具有自动发现和自动添加服务提供者的功能,但如果您使用的是Laravel 5.4.x及以下版本,请记得将其添加到/app/config/app.php中的providers数组中。

// ...
LaravelApiBase\Providers\LaravelApiBaseProvider::class,

最后,也是最关键的一点,此包提供了一个更新的Router,即LaravelApiBase\Services\ApiRouter,您必须在app/bootstrap/app.php文件中配置它以获得API的全部好处。您需要在文件中添加以下代码。

/**
 * Important change to ensure the right router version is used with the Laravel API Base package
 */
$app->singleton('router', LaravelApiBase\Services\ApiRouter::class);

使用库

以下示例假设您已经设置了数据库,只需要连接模型、控制器和路由。

对API进行请求

一旦您的API端点配置完成,您可以轻松地进行以下请求

标准的RESTful API请求

GET /todos         // Gets a paginated list to Todo items
GET /todos/{id}    // Get a specific Todo item by ID
POST /todos        // Create a new Todo record
PUT /todos/{id}    // Update a Todo record
DELETE /todos/{id} // Delete a Todo record

查询和分页结果

这是该包的亮点,使您能够灵活地处理API端点。

GET /todos?limit=5         // Get the first 5 items
GET /todos?page=3&limit=3  // Get page 3 of items with only 3 items

搜索/过滤数据

您可以使用模型中包含的任何字段进行搜索和过滤,并应用操作符以增强查询。

GET /todos?title=My Todo            // Get all Todos with a title "My Todo"
GET /todos?description_like=Call    // Returns any todos with the word "call" in the description
GET /todos?id_gt=5&title_like=John  // Gets all todos with an ID greater than 5 and have "John" in the title
GET /todos?id_in=1,3,5              // Gets a specific set of todos by ID
GET /todos?description_isNull       // Get all Todos with a NULL description

可用的搜索操作符

  • _eq - 等于操作符。默认。
  • _like - 使用LIKE {term}%操作。
  • _has - 使用LIKE %{term}%操作。
  • _sw - 以...开始。使用LIKE {term}%操作。
  • _ew - 以...结束。使用LIKE %{term}操作。
  • _gt - 大于操作符
  • _gte - 大于等于操作符
  • _lt - 小于操作符
  • _lte - 小于等于操作符
  • _in - IN操作符
  • _notIn - NOT IN操作符
  • _not - NOT操作符
  • _isNull - IS NULL操作符
  • _isNotNull - IS NOT NULL操作符

与关联模型一起工作

您可以返回Laravel Eloquent模型中with()操作支持的任何类型的模型关联。

GET /todos?contain=subtask                   // Get all Todos with associated subtasks
GET /todos?contain=subtask.assignee          // Get all Todos with subtasks and subtask assignee
GET /todos?contain=user,subtask              // Get all Todos with associated users and subtasks

// Counting associated models
GET /todos?count=subtask                     // Returns a `subtask_count` property in returned results

// Returning Associated Models in response after Creating or Updating a Resource
POST /todos?contain=subtask                  // Returns a subtask property in the response
PUT /todos/{id}?contain=subtask.assignee     // Returns a subtask property with its assignee property in the response

// Return associations from models with longer names
GET /todos?contain=todo-category             // Underscore or Hyphens are both supported

排序结果

您还可以在查询时按任何字段排序结果。

GET /todos?sort=id:desc                      // Get results sorted by ID Desc
GET /todos?sort=id:desc,title:asc            // Sort by multiple columns

配置您的应用程序

现在您已经知道可以做什么,让我们看看如何设置一切,以便您可以尝试使用它。本节假设您有一个名为todos的数据库表。我们将为该特定端点设置模型、控制器、FormRequest和JSONResource。

设置您的模型

要访问数据,您需要一个模型。

<?php

namespace App\Models;

use LaravelApiBase\Models\ApiModel;

class Todo extends ApiModel
{

    protected $table = 'todos';

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

    public function user() {
       return $this->belongsTo(User::class);
    }

    public function subtask() {
       return $this->hasMany(Subtask::class);
    }

    public function todoCategory() {
       return $this->belongsTo(TodoCategory::class);
    }
}

您还可以实现ApiModelInterface并使用ApiModelBehavior特性,对于不能直接扩展ApiModel类的现有模型,例如默认的User模型。

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use LaravelApiBase\Models\ApiModelInterface;
use LaravelApiBase\Models\ApiModelBehavior;

class User extends Authenticatable implements ApiModelInterface
{
    use Notifiable, ApiModelBehavior;

    // ...
}

鼓励使用可观察对象

在处理API模型时,我们鼓励您使用观察者来监听和响应该模型中的事件,以实现最干净的代码。示例

<?php

namespace App\Observers;

class TodoObserver
{

    public function sendReminder(Todo $todo) {
         // some logic to send a reminder
    }

    /**
     * Sends a reminder when a new Todo is added
     */
    public function created(Todo $todo) {
        $this->sendReminder($todo);
    }

    /**
     * Appends a timestamp at the end of the description
     */
    public function updating(Todo $todo) {
        $todo->description = $todo->description . ' Updated at ' . date('Y-m-d H:i:s');
    }
}

然后,在您的app\Providers\EventServiceProvider.php文件中,您可以连接您的观察者到您的模型

<?php

namespace App\Providers;

use App\Models\Todo;
use App\Observers\TodoObserver;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();

        Todo::observe(TodoObserver::class);
    }
}

设置输入验证请求

在创建或更新记录时,我们通常需要验证输入。创建一个请求对象可以使其在幕后发生。

<?php

namespace App\Http\Requests;

use LaravelApiBase\Http\Requests\ApiFormRequest;

class TodoRequest extends FormRequest implements ApiFormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|string',
            'description' => 'required|string'
        ];
    }

    /**
     * Returns an array of descriptions and examples for the fields being validated
     * so the documentation for the endpoints can be validated
     */
    public function bodyParameters() {
        return [
            'title' => [
                'description' => 'Title of Todo',
                'example' => 'Publish Library'
            ],
            'description' => [
                'description' => 'Description of task',
                'example' => 'Remember to publish library code'
            ]
        ];
    }
 }

设置JSON资源以格式化响应

您可以通过创建一个 LaravelApiBase\Http\Resources\APIResource 的子类来自定义返回给用户的响应

<?php

namespace App\Http\Resources;

use LaravelApiBase\Http\Resources\ApiResource;

class TodoResource extends ApiResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        $url = 'https://via.placeholder.com/150';

        return array_merge(parent::toArray($request), [
            'url' => $url
        ]);
    }
}

设置您的控制器

只需指定要使用的模型,控制器就会推断所需的资源或请求对象,并将它们用于所有的RESTful端点

<?php

namespace App\Http\Controllers;

use App\Models\Todo;
use LaravelApiBase\Http\Controllers\ApiControllerBehavior;

/**
 * By default, this Controller will locate the `App\Http\Requests\TodoRequest` and `App\Http\Resources\TodoResource`
 * classes and use them for Request Validation and Response Formatting.
 */
class TodoController extends Controller
{
    use ApiControllerBehavior;

    public function __construct(Todo $todo) {
        $this->setApiModel($todo);
    }

    // you can add additional methods here as needed and connect them in your routes file

    /**
     * Hypothetical Method To Return Subtasks
     */
    public function subtasks(Request $request, $id) {
        $subtasks = Todo::find($id)->subtasks;

        return $this->Resource::collection($subtasks);
    }
}

如果您的请求和资源类不位于默认目录中,即 App\Http\RequestsApp\Http\Resources,您可以在控制器中的 __construct() 函数中覆盖自动路径解析

<?php

namespace App\Http\Controllers;

use App\Models\Todo;
use App\Http\Requests\Specials\SpecialTodoRequest;
use App\Http\Resources\Specials\SpecialTodoResource;
use LaravelApiBase\Http\Controllers\ApiController;

class TodoController extends Controller
{
    use ApiControllerBehavior;

    public function __construct(Todo $todo) {
        $this->setApiModel($todo);
        $this->setApiFormRequest(SpecialTodoRequest::class);
        $this->setApiResource(SpecialTodoResource::class);
    }
}

配置Todo端点的路由

一旦设置完毕,您现在可以添加一个使资源可用的路由。您应该将这些添加到 routes/api.php 文件中。

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

// Add a special endpoint for returns subtasks of a Todo. These must come BEFORE the apiResource call
Route::get('todos/{id}/subtasks', 'TodoController@subtasks');

// adds all the basic endpoints for GET, POST, PUT, DELETE as well as /search and /count
Route::apiResource('todos', 'TodoController');

生成API文档

此库旨在与 Scribe 文档生成器 一起使用。安装库并运行以下命令以生成文档。

php artisan scribe:generate

提交错误和功能请求

错误和功能请求在 GitHub 上跟踪

作者

Francis Adu-Gyamfi - https://www.linkedin.com/in/francis-adu-gyamfi-3b782716/
请参阅参与此项目的 贡献者列表

许可证

Laravel API Base 采用 MIT 许可证授权 - 请参阅 LICENSE 文件以获取详细信息

致谢

此库得以实现,得益于 Matrix Designs 团队开发人员的启发。