js361014/plankton

PHP RESTful API 微框架

0.3.4.3 2022-07-24 18:57 UTC

This package is auto-updated.

Last update: 2024-09-24 23:48:00 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();