foxdie/rest

PHP RESTful API 微型框架

0.3.4 2020-05-27 08:19 UTC

This package is auto-updated.

Last update: 2024-09-28 17:49:25 UTC


README

需求

  • PHP >= 7.2
  • PHP cURL 扩展
  • Apache HTTP 服务器 >= 2.4
  • Apache mod_rewrite 已启用

安装

composer require foxdie/rest

目录

客户端

创建客户端

use Plankton\Client\Client;
	
$client = new Client(API_ENDPOINT);

完整示例在此:https://github.com/foxdie/rest/blob/master/Test/public/simple-client.php

GET 示例

$response = $client->get("/users");

使用回调

$client->get("/users", function(Response $response){
	echo $response;
});

使用魔法

$response = $client->getUsers();

POST 示例

$response = $client->post("/users", ["email" => "foo@bar.com"]);

使用回调

$client->post("/users", ["email" => "foo@bar.com"], function(Response $response){
	echo $response->getLocation();
});

使用魔法

$response = $client->postUsers(["email" => "foo@bar.com"]);

PUT、PATCH 和 DELETE 示例

完整示例在此:https://github.com/foxdie/rest/blob/master/Test/public/simple-client.php

魔法调用

脊柱骨命名法

如果您想使用魔法调用,则您的路由必须使用脊柱骨命名法 示例

$client->getUserAccounts()

将匹配以下路由

GET /user-accounts

不支持驼峰命名法和蛇形命名法

示例

内容类型

当您使用魔法调用(例如 $client->postUsers([]);)或 Client::post()Client::put()Client::patch() 中的任何一种方法时,会自动添加 Content-Type 头。根据您发送到服务器的数据自动猜测 Content-Type

但是,您仍然可以使用 自定义请求 手动设置 Content-Type

自定义请求示例

use Plankton\Client\Client;
use Plankton\Request;

$request = new Request(API_ENDPOINT . "/users");
$request
    ->setMethod(Request::METHOD_POST)
    ->setParameter("foo", "bar")
    ->setHeader("User-Agent", "Mozilla/5.0")
    ->setContentType(Request::CONTENT_TYPE_JSON)
    ->setData(["email" => "foo@bar.com"]);

$client = new Client(API_ENDPOINT);
$client->send($request, function(Response $response){
    // ...
});

自动数据转换

出于可读性原因,您可以使用 arraysobjectsRequest::setData() 方法,而不管您使用的内容类型是什么。数据将根据以下规则自动转换

身份验证策略

匿名身份验证

$client = new Client(API_ENDPOINT);

基本身份验证

use Plankton\Client\Strategy\BasicAuthentication;

$client = new Client(API_ENDPOINT, new BasicAuthentication(USER, PASSWORD));

客户端凭证

use Plankton\Client\Strategy\ClientCredentialsAuthentication;

$client = new Client(API_ENDPOINT, new ClientCredentialsAuthentication(
	CLIENT_ID, 
	CLIENT_SECRET,
	AUTHENTICATION_URL
));

授权和访问/刷新令牌请求将自动执行。第 3 个参数是可选的,默认值是 "/token"

服务器

创建服务器

use Plankton\Server\Server;

$server = new Server();
$server->run();

完整示例在此:https://github.com/foxdie/rest/blob/master/Test/public/simple-server.php

创建控制器

您必须创建至少一个扩展 Plankton\Server\Controller 抽象类的控制器

use Plankton\Server\Controller;

class APIController extends Controller{
	public function getUsers(int $id, Request $request): Response{
	}
	
	public function postUsers(Request $request): Response{
	}
}

您的控制器将包含您的 API 每个操作的公共方法。

您可以通过两种不同的方式创建路由

  • 使用配置文件
  • 使用注解

使用配置文件

这将自动禁用注解解析器。路由描述在一个 YAML 文件中

配置文件示例
routes:
    get-user:
        path: /users/{id}
        method: GET
        controller: Test\Controller\APIController::getUser
    create-user:
        path: /users
        method: POST
        controller: Test\Controller\APIController::createUser

完整示例在此:https://github.com/foxdie/plankton/blob/master/Test/config/server.yml

配置服务器
use Plankton\Server\{Server, Config};

$server = new Server(new Config(CONFIG_PATH));

完整示例在此:https://github.com/foxdie/plankton/blob/master/Test/public/config-server.php

使用注解

use Plankton\Server\Controller;

class APIController extends Controller{
	/**
	 * @Route(/users/{id})
	 * @Method(GET)
	 */
	public function getUser(int $id, Request $request): Response{
	}
	
	/**
	 * @Route(/users)
	 * @Method(POST)
	 */
	public function createUser(Request $request): Response{
	}
}

将根据 @Route 和 @Method 注解自动创建路由。

完整示例在此 : https://github.com/foxdie/rest/blob/master/Test/Controller/APIController.php

@Route 注解
  • 接受正则表达式
  • 接受占位符:它们将按出现的顺序作为参数传递
  • 强烈建议使用脊柱骨命名法

您可以为控制器添加路由前缀

/**
 * @Route(/users)
 */
class APIController extends Controller{
	/**
	 * @Route(/{id})
	 * @Method(GET)
	 */
	public function getUser(int $id, Request $request): Response{
	}
	
	/**
	 * @Route(/)
	 * @Method(POST)
	 */
	public function createUser(Request $request): Response{
	}
}
@Method 注解

可能的值包括

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
@Exception 注解
class APIController extends Controller{
	/**
	 * This will catch any \CustomNameSpace\CustomException
	 * @Exception(CustomNameSpace\CustomException)
	 */
	public function catchCustomException(Exception $e, Request $request): Response{
	}
	
	/**
	 * This will catch all other exceptions
	 * @Exception(*)
	 */
	public function catchException(Exception $e, Request $request): Response{
	}
}

注册控制器

use Plankton\Server\Server;

$server = new Server();
$server
	->registerController(new APIController());
	->registerController(...);
	->run();

完整示例在此:https://github.com/foxdie/rest/blob/master/Test/public/simple-server.php

创建中间件

(这是可选的)您必须实现Plankton\Server\Middleware接口。中间件可以处理传入的请求和发出的响应。

use Plankton\Server\{Request, Response};
use Plankton\Server\{Middleware, RequestDispatcher};

class BasicAuthenticationMiddleware implements Middleware{
	public function process(Request $request, RequestDispatcher $dispatcher): Response{
		// ...
		return $dispatcher->process($request);
	}
}

完整示例请参阅此处:https://github.com/foxdie/rest/blob/master/Test/Middleware/BasicAuthenticationMiddleware.php

注册中间件

use Plankton\Server\Server;

$server = new Server();
$server
	->addMiddleware(new BasicAuthenticationMiddleware())
	->addMiddleware(...)
	->registerController(new APIController())
	->run();

OAuth2

客户端凭证授权

客户端

use Plankton\Client\Client;
use Plankton\Client\Strategy\ClientCredentialsAuthentication;
use Plankton\Response;

$client = new Client(API_ENDPOINT, new ClientCredentialsAuthentication(
	CLIENT_ID, 
	CLIENT_SECRET,
	AUTHENTICATION_URL
));

完整示例请参阅此处:https://github.com/foxdie/rest/blob/master/Test/public/oauth2-client.php

服务器

use Plankton\Server\Server;
use OAuth2\Middleware\ClientCredentialsMiddleware;
use OAuth2\Provider\MemoryProvider;
use Test\Controller\APIController;

// Access Token provider
$provider = new MemoryProvider();
$provider->addClient(CLIENT_ID, CLIENT_SECRET);

$server = new Server();
$server
	->addMiddleware(new ClientCredentialsMiddleware($provider))
	->registerController(new APIController())
	->run();

完整示例请参阅此处:https://github.com/foxdie/rest/blob/master/Test/public/oauth2-server.php

创建自己的访问令牌提供者

您只需实现AccessTokenProvider接口

use Plankton\OAuth2\Provider\AccessTokenProvider;
use Plankton\OAuth2\Token\{AccessToken, BearerToken};

class PDOProvider implements AccessTokenProvider{
	/**
	 * return a new/issued Access Token if you find a client matching the authentication parameters (id + secret)
	 */
	public function getAccessToken(string $client_id, string $client_secret): ?AccessToken{
	}

	/**
	 * return a new Access Token if the Refresh Token is valid
	 */
	public function refreshToken(string $refreshToken): ?AccessToken{
	}

	/**
	 * authorize or not the given Access Token
	 */
	public function isValidAccessToken(string $token): bool{
	}
}

日志记录

客户端

简单记录器

use Plankton\Logging\SimpleLogger;

$client->setLogger(new SimpleLogger());

// ... do some requests

foreach ($client->getLogger()->getLogs() as $request) {
	$response = $client->getLogger()->getLogs()[$request];
}

完整示例在此:https://github.com/foxdie/rest/blob/master/Test/public/simple-client.php

XML 记录器

use Plankton\Logging\XMLLogger;

$client->setLogger(new XMLLogger());

// ... do some requests

header("Content-type: text/xml");
echo $client->getLogger()->getLogs()->asXML();

完整示例请参阅此处:https://github.com/foxdie/rest/blob/master/Test/public/oauth2-client.php

自定义记录器

您必须实现Plankton\Request\Logger接口

use Plankton\{Request,Response};
use Plankton\Request\Logger

class CustomLogger implements Logger{
	public function log(Request $request, Response $response = NULL): void{
	}
}

服务器

您可以通过添加中间件轻松记录请求和响应

use Plankton\{Request,Response};
use Plankton\Server\{Middleware, RequestDispatcher};

class LogMiddleware implements Middleware{
	public function process(Request $request, RequestDispatcher $dispatcher): Response{		
		$response = $dispatcher->process($request);
		
		// log $request and $response here
		
		return $response
	}
}

然后注册中间件(#registering-the-middlewares)

use Plankton\Server\Server;
use Test\Controller\APIController;
use Test\Middleware\LogMiddleware;

$server = new Server();
$server
	->addMiddleware(new LogMiddleware())
	->registerController(new APIController())
	->run();