搭建 API 服务
在实战项目中,为了和别的项目进行一些必要的对接,你的web应用可能 需要提供一些必要的api,而为了统一管理api,你可能需要搭建一个api服务专门用来提供便捷的远程api调用。
Herosphp为你提供了体验极佳 API 服务的架构方案,供你参考, 目前支持普通的 Http API 接口服务,后期会增加 JSONRPC API 服务支持。
在开始构建 API 服务之前,你必须先把你的 herosphp 的版本升级到 v3.0.5 及以上版本 在 composer.json 文件中修改版本之后,执行 composer update
命令即可以。
1. 建立一个 api 的模块
你需要把你所有对外的服务都放置在 api 模块中, api 模块的文件结构是这样的:
|-- api
|---- service
|---- ModuleListener.php
api 模块的结构很简单,就一个 service
文件夹,里面放置了你需要对外提供的服务。还有一个 ModuleListener
类,用来做当前模块的请求监听。 不过这个 ModuleListener
并不像其他模块的 ModuleListener
一样,它实现的是 IApiListener
接口,而不是 IWebAplicationListener
接口:
namespace app\api;
use herosphp\api\interfaces\IApiListener;
/**
* API 模块监听器,这里需要实现系统通用 IApiListener 接口
* @author yangjian<yangjian102621@gmail.com>
*/
class ModuleListener implements IApiListener {
/**
* white list
* @var array
*/
private static $whiteList = array(
'/user/register' => 1
);
/**
* API authorization interception processing
* @param $params
* @return bool
*/
public function authorize($params = null)
{
// TODO: Implement authorize() method.
return true;
}
/**
* determine if a request need authrization
* @param $url
* @return bool
*/
public function needAuthrize($url)
{
if (!isset(self::$whiteList[$url])) {
return true;
} else {
return false;
}
}
}
这里你需要自己实现两个方法,一个是 API 授权认证的拦截方法 authorize()
, 你可以在这里做同意的 API 调用权限认证,通过修改静态变量 $whiteList
来配置放行的白名单。 然后在通过实现 needAuthrize($url)
方法来决定哪些 API 请求是否需要授权认证。
恩,这样就可以了,操作简单,功能强大。
2. 添加入口文件
正如 web 应用需要一个 index.php
入口文件一样,你也需要在项目根目录(app)下创建一个入口文件,默认是 api.php
, 跟 index.php
类似,也就 2 行代码
/**
* API 应用入口程序
* @author yangjian
* @since v3.0.0
*/
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:GET,POST');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
require_once __DIR__."/server.php";
\herosphp\BootStrap::runApi(); // 启动 API 应用程序
前面三行代码是为了允许 javascript 通过 ajax 跨域访问.
编写服务
接下来你就可以开始编写你的 API 服务了,需要注意的是,所有的服务都必须放在 api/service
目录下,然后就像写普通服务一样就可以了,不需要继承某个类或者实现某个接口, 直接写就行,下面是 demo:
namespace app\api\service;
use herosphp\utils\JsonResult;
class UserService
{
/**
* user login service
* @param $username
* @param $password
*/
public function login($username, $password)
{
if ($username == "rock" && $password == "123456") {
JsonResult::success("login success.");
} else {
JsonResult::fail("login failed.");
}
}
/**
* create a new user
* @param $username
* @param $password
* @param $mobile
*/
public function register($username, $password, $mobile)
{
JsonResult::success("register success.");
}
}
注意:所有需要对外暴露的 API 方法都需要定义成 public
添加 Nginx 配置文档
我们这里 API 模块是单独作为应用对外提供服务的,这样方便你绑定独立的域名, 你需要在 nginx
的配置目录下增加一个配置文档,内容如下:
server {
listen 80;
server_name api.herosphp.com;
root /php/herosphp-app;
index index.php;
#设定本虚拟主机的访问日志
access_log /dev/null;
error_log /dev/null;
# Make site accessible from http://localhost/
location ~ .*\.(php|php5)?$
{
fastcgi_pass unix:/var/run/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#add surpport pathinfo visitd mode
if (!-f $request_filename) {
rewrite ^/.*$ /app/api.php last;
break;
}
}
添加 hosts 文件映射
在 hosts 文件中加入如下映射:
127.0.0.1 api.herosphp.com
测试
API 的路径访问形式为 /{serviceName}/{methodName}, 如 /user/login
其实对应提供服务的就是 UserService::login
方法。
请求传参的名称需要跟服务对应形参名称相同
curl http://api.herosphp.com?username=rock&password=123456
返回的是 JSON 格式的数据:
{
"code": 404,
"success": false,
"message": "Invalid resource path.",
"data": null,
"count": null,
"page": null,
"pagesize": null,
"extra": null
}