搭建 API 服务

优质
小牛编辑
137浏览
2023-12-01

在实战项目中,为了和别的项目进行一些必要的对接,你的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
}