jdesrosiers/resourceful

一个用于快速原型设计REST应用的框架

dev-master 2022-10-15 23:24 UTC

This package is auto-updated.

Last update: 2024-09-16 03:21:17 UTC


README

Build Status Code Coverage Scrutinizer Code Quality

Resourceful 是一套在 Silex(Silex)之上构建的工具集,通过消除样板代码来简化基于JSON的Hypermedia API的构建过程。在大多数情况下,HTTP方法、头部等都是定义良好的,但这些通常由开发者每次创建新API时重新实现。如果你不熟悉HTTP规范,其中一些细节很容易出错。Resourceful 旨在通过处理这些细节来帮助你,以便你能够专注于API的设计。

Resourceful最初是为了快速原型设计而构建的,因此它为你做了很多工作。然而,你可以选择让Resourceful处理哪些部分,以及你想要自己处理哪些部分。当你把所有东西组合在一起时,你将得到一个非常有用的工具,用于快速原型设计Hypermedia API,你几乎不需要写除了JSON Hyper-Schemas之外的其他代码。本文件从基础知识开始,并在每个部分中添加新功能。

安装

使用composer安装Resourceful

> composer require jdesrosiers/resourceful

Resourceful应用

您希望从Resourceful中得到的最基本的是Resourceful应用。这个类实现了Silex\Application,可以像使用Silex应用一样使用它。Resourceful应用通过内容协商、OPTIONS方法支持、CORS支持和JSON中的错误处理装饰了Silex应用。这是任何基于JSON的REST API都应该做的事情的最基本的工作。

快速入门

<?php

use JDesrosiers\Resourceful\Resourceful;
use Silex\Application;

require __DIR__ . "/vendor/autoload.php";

$app = new Resourceful();
$app["debug"] = true;

// Register Controllers
$app->get("/hello/{subject}", function (Application $app, $subject) {
    return $app->json(["greeting" => "Hello $subject!!!"]);
});

// Initialize CORS support
$app->after($app["cors"]);

$app->run();

内容协商

Resourceful默认只支持JSON。这可以通过配置来覆盖,但高级功能基于JSON Schema和JSON Hyper-Schema,所以除了JSON之外的其他支持意味着你将无法使用高级功能。

对JSON格式之外的任何请求都将导致406 Not Acceptable响应。任何传递非JSON内容的请求都将导致415 Unsupported Media Type响应。内容协商支持由silex-conneg-provider服务提供者提供。

对OPTIONS请求的支持

我认为没有人关心OPTIONS请求支持,除非他们需要它来进行CORS,但为了HTTP兼容性,拥有它总是好的。Resourceful从jdesrosiers/silex-cors-provider服务提供者那里获得OPTIONS请求支持。

CORS支持

CORS支持由jdesrosiers/silex-cors-provider服务提供者提供。要启用CORS支持,在中间件后添加cors到您的应用程序中。

资源控制器

资源控制器旨在消除在实现REST API中常用的CRUD操作所涉及的样板代码。资源控制器接受实现Doctrine\Common\Cache\Cache接口的实现。这允许你实现简单的存储功能,并允许资源控制器处理HTTP细节。验证使用JSON Schema进行。

快速入门

<?php

use Doctrine\Common\Cache\FilesystemCache;
use JDesrosiers\Resourceful\Controller\CreateResourceController;
use JDesrosiers\Resourceful\Controller\DeleteResourceController;
use JDesrosiers\Resourceful\Controller\GetResourceController;
use JDesrosiers\Resourceful\Controller\PutResourceController;
use JDesrosiers\Resourceful\Resourceful;

require __DIR__ . "/vendor/autoload.php";

$app = new Resourceful();
$app["debug"] = true;

$data = new FilesystemCache(__DIR__ . "/data");

// Register Controllers
$schema = file_get_contents(__DIR__ . "/schema/foo.json");
$app["json-schema.schema-store"]->add("foo", json_decode($schema));
$app->get("/foo/{id}", new GetResourceController($data))->bind("foo");
$app->put("/foo/{id}", new PutResourceController($data, "foo"));
$app->delete("/foo/{id}", new DeleteResourceController($data));
$app->post("/foo", new CreateResourceController($data, "foo"));

// Initialize CORS support
$app->after($app["cors"]);

$app->run();

Doctrine缓存

我选择了使用Doctrine缓存进行数据存储。他们提供了广泛的缓存实现,您可以从中选择,例如文件系统、memcache或redis。这类事情非常适合快速原型设计,但它很容易被更持久的存储所替代。您只需要编写一个实现Doctrine\Common\Cache\Cache接口的类。

JSON Schema

JSON Schema验证由jdesrosiers/silex-json-schema-provider服务提供者支持。

GetResourceContoller

如果请求的资源不存在,将返回404 Not Found响应。资源检索错误将导致503 Service Unavailable错误。成功将响应为200 OK

PutResourceController

可以使用PUT请求创建或修改资源。PUT请求不支持部分更新。传递的资源将按照传递的方式存储。修改后的资源将随响应返回。请求正文将通过jdesrosiers/silex-json-schema-provider进行验证。如果验证失败,将返回400 Bad Request响应。如果资源之前不存在,则响应为201 Created,否则为200 OK

DeleteResourceController

当资源被DELETE时,将响应204 No Content。删除一个不存在的资源并不被视为错误。

CreateResourceController

使用POST创建资源时,将有一个指向新创建资源的Link头。资源创建总是响应为201 Created。新资源将在响应中回显。此控制器接受PHP的uniqid函数生成的唯一ID,并使用jdesrosiers/silex-json-schema-provider验证请求。如果验证失败,将返回400 Bad Request响应。在现实生活中,资源创建通常需要更多操作,或者您可能希望以不同的方式生成ID。因此,与其他三个控制器相比,此控制器可能不太有用。

Hypermedia Support

ResourcefulServiceProvider添加了创建JSON Hyper-Schema驱动的API的工具。为了支持由hyper-schema驱动的API,您需要将响应与hyper-schemas关联,并为客户端提供服务以发现链接。

快速入门

<?php

use Doctrine\Common\Cache\FilesystemCache;
use JDesrosiers\Resourceful\Controller\CreateResourceController;
use JDesrosiers\Resourceful\Controller\DeleteResourceController;
use JDesrosiers\Resourceful\Controller\GetResourceController;
use JDesrosiers\Resourceful\Controller\PutResourceController;
use JDesrosiers\Resourceful\Resourceful;
use JDesrosiers\Resourceful\ResourcefulServiceProvider\ResourcefulServiceProvider;
use JDesrosiers\Resourceful\SchemaControllerProvider\SchemaControllerProvider;

require __DIR__ . "/vendor/autoload.php";

$app = new Resourceful();
$app["debug"] = true;

$app->register(new ResourcefulServiceProvider(), [
    "resourceful.schema-dir" => __DIR__
]);

$data = new FilesystemCache(__DIR__ . "/data");

// Register Supporting Controllers
$app->mount("/schema", new SchemaControllerProvider());

// Register Controllers
$schema = "/schema/foo";
$foo = $app["resources_factory"]($schema);
$foo->get("/{id}", new GetResourceController($data))->bind($schema);
$foo->put("/{id}", new PutResourceController($data, $schema));
$foo->delete("/{id}", new DeleteResourceController($data));
$foo->post("/", new CreateResourceController($data, $schema));
$app->mount("/foo", $foo);

// Initialize CORS support
$app->after($app["cors"]);

$app->run();

Schema Controller

ResourcefulServiceProvider有一个配置选项resourceful.schema-dir,允许您选择将存储模式的位置。这就是您将放置您编写的模式的地方。SchemaControllerProvider从该目录正确地提供模式。如果您正在使用资源控制器,除了编写hyper-schemas外,涉及到的编码很少。

resources_factory

resources_factory服务类似于Silex的controllers_factory,但它添加了将模式与控制器组关联的过滤器。它主要做的事情是将您的ContentType设置为application/json; profile="/schema/foo",这表明JSON响应由由profile标识的模式描述。有关详细信息,请参阅jdesrosiers/silex-json-schema-provider

Rapid Prototyping

此项目的原始目的是创建一个工具,用于使用JSON Hyper-Schema和Jsonary的通用JSON浏览器作为通用UI来设计Hypermedia API。本节中描述的最后一个工具是为了这个目的。您应该能够在仅编写少量代码的情况下完全描述您的API并与其交互。

快速入门

<?php

use Doctrine\Common\Cache\FilesystemCache;
use JDesrosiers\Resourceful\CrudControllerProvider\CrudControllerProvider;
use JDesrosiers\Resourceful\FileCache\FileCache;
use JDesrosiers\Resourceful\IndexControllerProvider\IndexControllerProvider;
use JDesrosiers\Resourceful\Resourceful;
use JDesrosiers\Resourceful\ResourcefulServiceProvider\ResourcefulServiceProvider;
use JDesrosiers\Resourceful\SchemaControllerProvider\SchemaControllerProvider;

require __DIR__ . "/vendor/autoload.php";

$app = new Resourceful();
$app["debug"] = true;

$app->register(new ResourcefulServiceProvider(), [
    "resourceful.schema-dir" => __DIR__
]);

$data = new FilesystemCache(__DIR__ . "/data");
$static = new FileCache(__DIR__ . "/static");

// Register Supporting Controllers
$app->mount("/schema", new SchemaControllerProvider());
$app->flush();
$app->mount("/", new IndexControllerProvider($static));

// Register Controllers
$app->mount("/foo", new CrudControllerProvider("foo", $data));

// Initialize CORS support
$app->after($app["cors"]);

$app->run();

Jsonary

Jsonary 是 JSON 超级模式 JavaScript 客户端。Jsonary 包含一个通用的 JSON 浏览器实现,该实现使用 Jsonary 为任何启用 JSON 超级模式的 API 提供通用 UI。假设您的 API 正在 http://localhost:8000 上提供服务,您可以使用位于 http://json-browser.s3-website-us-west-1.amazonaws.com/?url=http%3A//localhost%3A8000/ 的 JSON 浏览器部署来与您的 API 进行交互。

索引控制器

使您的超媒体 API 可被发现很大程度上取决于您,但 IndexControllerProvider 通过自动创建指向您应用程序根目录的索引模式,让您有一个良好的开端。您需要向索引模式添加链接,以指导用户如何使用您的应用程序。

CRUD 控制器提供者

CrudControllerProvider 为 CRUD 操作注册路由并生成一个带有基本操作的起始超模式,以帮助您开始。要添加新资源,您只需添加一行代码来安装 CrudControllerProvider 并编写相应的 JSON 模式以定义资源。

未来工作

以下是一些希望实现但尚未实现的功能。

列出控制器

提供一个资源列表的控制器对于快速原型设计非常重要。几乎任何真实世界的 API 都需要此类功能。到目前为止,阻止我这样做的主要原因是缺乏表示资源列表的标准方法。我尽可能地遵循现有的标准。我花了一些时间来思考如何处理这个问题,但最终没有采取行动。

PATCH

只要使用像 JSON Patch (RFC 6902) 这样的标准 mediatype,包含对 PATCH 的支持应该相当简单。

HTTP 缓存

我希望能在某些时候添加 HTTP 缓存头,并在适当的地方使用这些头。