diomac/php-api-rest
Composer 安装命令:
composer require diomac/php-api-rest
包简介
A PHP API REST Micro-Framework using annotations
关键字:
README 文档
README
PHP API REST framework using annotations, and Swagger 2.0 support.
Prerequisites
- PHP >=7.2
Optional (Recommended)
Caching routes
- nrk/predis (Redis) - https://github.com/nrk/predis Or
- Pecl APC - Alternative PHP Cache - https://pecl.php.net/package/apc
Swagger yaml format
- yaml pecl extension https://pecl.php.net/package/yaml
Installing
Use composer to manage your dependencies and download PHP-API-REST:
composer require diomac/php-api-rest
Get Started
API Rest Configuration
- 1 - Place an .htaccess file in the root folder of your Rest API (base url), to redirect all routes to the API initialization file.
Example API folders:
.htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !init\.php$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* init.php [L,QSA]
- 2 - Use the initialization file to import the dependencies of your project and...
- Instantiate a Diomac\API\AppConfiguration object;
- Set the base url of your API;
- Add the Resources Class Names of your API (See Implementing API Rest Resources);
- Instantiate a Diomac\API\App object using the configuration object;
- Finally call exec method.
init.php file:
use Diomac\API\App;
use Diomac\API\AppConfiguration;
/**
* Initializing API configuration
*/
$config = new AppConfiguration();
$config->setBaseUrl('/php-api-rest/example/v1');
/**
* Adding resources classes
*/
$config->addResource(\example\v1\ExampleResource::class);
$config->addResource(\example\v1\ExampleSwaggerJson::class);
/**
* Execute API
*/
try{
$app = new App($config);
$app->exec();
}catch (Exception $ex){
...
}
Implementing API Rest Resources
- 3 - In the resource class, enter the inheritance of the Resource class:
namespace example;
use Diomac\API\Resource;
use Diomac\API\Response;
use Diomac\API\UnauthorizedException;
class ExampleResource extends Resource
{
...
}
- 4 - For each method of the resource class, enter PHP annotation to identify routes (@route), HTTP methods (@method) and if you need a Class implementing Guard Interface to protect the route (@guard - See how implement guards in topic Implementing a Guard Class ):
/**
* @method get
* @route /auth/usr-data/id/{id}
* @guard(
* className="example\core\secure\ExampleGuard",
* @parameters(operationId="GETUSERDATA")
* )
*/
function getUsrData()
{
// ... your code
$this->response->setCode(Response::OK); // set HTTP response code
$this->response->setBodyJSON($jsonSerializable); // set responde data
return $this->response; // return response object
}
Resource Class Inheritance
- 5 - Whenever a route is executed, the class holding the route will be instantiated and inherit the following attributes:
A Diomac\API\Request object with the methods:
$this->request->getParams() // returns the parameters of the URL and $_GET
$this->request->getData() // returns an object sent by the front end
$this->request->getRoute() // returns the executed route
$this->request->getMethod() // returns the executed HTTP method
A Diomac\API\Response object with the methods:
$this->response->setHeader('name', 'value'); // set HTTP header response
$this->response->setCode(Response::BAD_REQUEST); // set HTTP response code
$this->response->setBody('string'); // set response body
$this->response->setBodyJSON(\JsonSerializable object); // set response body to convert in JSON
$this->response->setContentType(''); // set content type response (for setBodyJSON not needed)
And it inherits methods from the Diomac\API\Resource class:
$this->getRoute(); // returns the configured route
$this->getParams(); // returns the parameters of the URL and $_GET
$this->getParam('name'); // returns a parameter by name
Output
- 6 - For the output simply return the response object:
return $this->response;
Complete Resource example
API get method:
/**
* @method get
* @route /example/v1/pet/{petId}
*
* @return Response
* @throws Exception
*/
function getPet(): Response
{
try {
$petId = $this->getParam('petId');
$pet = new Pet($petId);
/**
* API Rest best practices - selecting returned fields and aliases
*/
$fields = $this->getParam('fields');
if($fields){
Response::setFields(explode(',', $fields), Pet::class);
}
$this->response->setCode(Response::OK);
$this->response->setBodyJSON($pet);
} catch (Exception $ex) {
throw new Exception('Internal Server Error', Response::INTERNAL_SERVER_ERROR);
}
return $this->response;
}
Guards
/**
* @method get
* @route /auth/usr-data/id/{id}
* @guard(
* className="example\core\secure\ExampleGuard"
* )
* @guard(
* className="example\core\secure\ExampleGuardWithParams",
* @parameters(operationId="GETUSERDATA", operationName="GETUSERDATA")
* )
*/
function getUsrData()
{
// ... your code
$this->response->setCode(Response::OK); // set HTTP response code
$this->response->setBodyJSON($ this->request->getData()); // set responde data
return $this->response; // return response object
}
Implementing a Guard Class
namespace api\secure;
use Diomac\API\Exception;
use Diomac\API\ForbiddenException;
use Diomac\API\UnauthorizedException;
use Diomac\API\Response;
use Diomac\API\Guard;
/**
* Class AuthGuard
* @package api\secure
*/
class AuthGuard implements Guard
{
/**
* @param object|null $guardParams
* @return bool
* @throws Exception
* @throws ForbiddenException
* @throws UnauthorizedException
*/
public function guard(object $guardParams = null) : bool
{
$func = $guardParams->func;
$access = checkAccess($func);
switch ($access) {
case Response::OK:
return true;
break;
case Response::UNAUTHORIZED:
throw new UnauthorizedException();
break;
case Response::FORBIDDEN:
throw new ForbiddenException();
break;
default:
throw new Exception('Server Error!', Response::INTERNAL_SERVER_ERROR);
}
}
}
Cache
Cache settings save the mapped routes into a list, and when used (set to true), skip the route mapping step for better performance.
Cache with APC - Alternative PHP Cache
**
* Setting use cache for caching of annotations mapping
*/
$config->setUseCache(true);
/**
* Execute API
*/
try{
$app = new App($config);
$app->exec();
}catch (Exception $ex){
...
}
Cache with Redis
/**
* Set Redis for cache
*/
$redis = new RedisConfig();
$redis->setScheme('tcp');
$redis->setHost('redis');
$redis->setPort(6379);
**
* Setting use cache for caching of annotations mapping
*/
$config->setUseCache(true, $redis);
Swagger 2.0 support
swagger.json or swagger.yaml
Create a route in a resource like the example below:
PHP Class:
use Diomac\API\Resource;
use Diomac\API\Response;
use example\v1\doc\ExampleSwaggerDoc;
class ExampleSwaggerJson extends Resource
{
/**
* @method get
* @route /swagger.json
*/
function swaggerJson()
{
$this->response->setCode(Response::OK);
$swagger = new ExampleSwaggerDoc();
/**
* JSON
*/
$this->response->setBodySwaggerJSON($swagger);
/**
* Or YAML
*/
//$this->response->setBodySwaggerYAML($swagger);
return $this->response;
}
}
Route result:
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Swagger Sample App",
"description": "This is a sample server Petstore server.",
"termsOfService": "http:\/\/swagger.io\/terms\/",
"contact": {
"name": "API Support",
"email": "support@swagger.io",
"url": "http:\/\/swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http:\/\/www.apache.org\/licenses\/LICENSE-2.0.html"
}
},
"host": "localhost",
"basePath": "\/php-api-rest\/vendor\/example\/v1",
"schemes": [
"http",
"https"
],
"consumes": [
"text\/plain; charset=utf-8"
],
"produces": [
"application\/json",
"text\/html"
],
"tags": [
{
"name": "ExampleAPIDocSwagger",
"description": "ExampleAPIDocSwagger",
"externalDocs": {
"description": "Externaldocsexample",
"url": "http:\/\/example_php_api_rest.com"
}
}
],
"paths": {
...
Swagger Info
To document the information (Swagger Info) of your API, you can use Swagger and SwaggerInfo classes. Just implement an "ExampleSwaggerDoc" class that inherits from Swagger as in the example below:
PHP Class:
use Diomac\API\swagger\Swagger;
use Diomac\API\swagger\SwaggerInfo;
class ExampleSwaggerDoc extends Swagger
{
public function info(): SwaggerInfo
{
$this->setInfo(new SwaggerInfo());
$this->info->setVersion('1.0.0');
$this->info->setTitle('Swagger Sample App');
$this->info->setDescription('This is a sample server Petstore server.');
$this->info->setTermsOfService('http://swagger.io/terms/');
$this->info->getContact()->setName('API Support');
$this->info->getContact()->setEmail('support@swagger.io');
$this->info->getContact()->setUrl('http://swagger.io');
$this->info->getLicense()->setName('Apache 2.0');
$this->info->getLicense()->setUrl('http://www.apache.org/licenses/LICENSE-2.0.html');
return $this->getInfo();
}
...
}
@tag
Use @tag in PHPDoc Class to document Resources's routes with Swagger Tag Object.
PHPDoc:
/**
* Class ExampleResource
* @package example\v1
* @tag(
* name="Example API Doc Swagger",
* description="Example API Doc Swagger",
* @externalDocs(description="External docs example", url="http://example_php_api_rest.com")
* )
*/
class ExampleResource extends Resource
{
...
}
Swagger json result:
...
"tags": [
{
"name": "ExampleAPIDocSwagger",
"description": "ExampleAPIDocSwagger",
"externalDocs": {
"description": "Externaldocsexample",
"url": "http:\/\/example_php_api_rest.com"
}
}
],
...
@tag (string)
Use @tag in PHPDoc function to document your route with a additional tag.
PHPDoc:
/**
* @method get
* @route /example/api/value1/{value1}/value2/{value2}
* @tag More one tag
*/
function getUsrData(): Response
{
...
}
Swagger json result:
...
"tags": [
"More one tag",
"ExampleAPIDocSwagger"
],
...
@contentType
Use @contentType in PHPDoc function to document your route with Swagger produces [string].
PHPDoc:
/**
* @method get
* @route /example/api/value1/{value1}/value2/{value2}
* @contentType application/json
* @contentType text/html
*/
function getUsrData(): Response
{
...
}
Swagger json result:
...
"produces": [
"application\/json",
"text\/html"
],
...
@summary
Use @summary in PHPDoc function to document your route with Swagger summary string.
PHPDoc:
/**
* @method get
* @route /example/api/value1/{value1}/value2/{value2}
* @summary Example api rest php
*/
function getUsrData(): Response
{
...
}
Swagger json result:
...
"get": {
"summary": "Example api rest php",
...
@description
Use @description in PHPDoc function to document your route with Swagger description string.
PHPDoc:
/**
* @method get
* @route /example/api/value1/{value1}/value2/{value2}
* @description A example api rest php
*/
function getUsrData(): Response
{
...
}
Swagger json result:
...
"get": {
"description": "A example api rest php",
...
@operationId
Use @operationId in PHPDoc function to document your route with Swagger operationId string.
PHPDoc:
/**
* @method get
* @route /example/api/value1/{value1}/value2/{value2}
* @operationId GETUSERDATA
*/
function getUsrData(): Response
{
...
}
Swagger json result:
...
"get": {
"operationId": "GETUSERDATA",
...
@consumeType
Use @consumeType in PHPDoc function to document your route with Swagger consumes [string].
PHPDoc:
/**
* @method get
* @route /example/api/value1/{value1}/value2/{value2}
* @consumeType text/plain; charset=utf-8
*/
function getUsrData(): Response
{
...
}
Swagger json result:
...
"post": {
"consumes": [
"text\/plain; charset=utf-8"
],
...
@response(...)
Use @response(...) in PHPDoc function to document your route with Swagger response object.
PHPDoc:
/**
* @method get
* @route /example/api/value1/{value1}/value2/{value2}
* @response(
* code=200,
* description="Success",
* @schema(
* type="object",
* @items($ref="#/definitions/sucess")
* )
* )
*/
function getUsrData(): Response
{
...
}
Swagger json result:
...
"responses": {
"200": {
"description": "Success",
"schema": {
"type": "object",
"items": {
"$ref": "#\/definitions\/sucess"
}
}
},
...
License
This project is licensed under the MIT License - see the LICENSE file for details
diomac/php-api-rest 适用场景与选型建议
diomac/php-api-rest 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 67 次下载、GitHub Stars 达 9, 最近一次更新时间为 2018 年 07 月 30 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「rest」 「api」 「micro-framework」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 diomac/php-api-rest 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 diomac/php-api-rest 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 diomac/php-api-rest 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A simple and extensible PHP micro-framework.
Minimalistic Kernel and Routers based on Symfony Components
Micro-Kernel for PHP Applications
Minimalistic Kernel and Routers based on Symfony Components
A PSR-7 compatible library for making CRUD API endpoints
Api bundle
统计信息
- 总下载量: 67
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 10
- 点击次数: 0
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2018-07-30
