# 如何请求接口服务
## HTTP协议下的请求方式
对于PhalApi,默认是通过HTTP协议进行通信的。根据接口服务的具体实现,可以使用GET或POST方式请求。
## 访问入口
如前面所言,PhalApi推荐将系统对外可访问的根目录设置为/path/to/phalapi/public。PhalApi的统一访问入口文件是/path/to/phalapi/index.php文件。
当配置的域名为:dev.phalapi.net,并且已将根目录设置到public,此时访问的URL是:
```
http://dev.phalapi.net
```
当未配置域名,亦未配置根目录时,此时访问的URL是(显然更长更不优雅):
```
http://localhost/phalapi/public/index.php
```
如果尚未安装,请先阅读[下载与安装](download-and-setup)。
## 如何指定待请求的接口服务?
默认情况下,可以通过s参数指定待请求的接口服务,当s未传时,缺省使用默认接口服务,即:App.Site.Index。以下三种方式是等效的,都是请求默认接口服务。
+ 未传s参数
+ ?s=Site.Index,省略命名空间,默认使用App
+ ?s=App.Site.Index,带有命名空间前缀
也就是说,当请求除默认接口服务以外的接口服务时,其格式可以二选一:
+ ?s=Class.Action
+ 或者:?s=Namespace.Class.Action
其中,Namespace表示命名空间前缀,Class为接口服务类名,Action为接口服务方法名,这三者通常首字母大写,并使用英文点号分割。最终执行的类方法是:Namespace/Api/Class::Action()。需要注意的是:
> 温馨提示:s参数为service参数的缩写,即使用```?s=Class.Action```等效于```?service=Class.Action```,两者都存在时优先使用service参数。
### 关于Namespace命名空间
Namespace是指命名空间中```/Api/```的前半部分。并且需要在根目录下的composer.json文件中进行autoload的注册,以便能正常自动加载类文件。如默认已经注册的App命名空间:
```
{
"autoload": {
"psr-4": {
"App\\": "src/app"
}
}
}
```
当命名空间存在子命名空间时,在请求时使用下划线分割。反过来,当不存在多级命名空间时,命名空间不应该含有下划线。
### 关于Class接口服务类名
Class接口服务类名是指命名空间中```/Api/```的后半部分,并且必须是[PhalApi/Api](https://github.com/phalapi/kernal/blob/master/src/Api.php)的子类。当命名空间存在子命名空间时,在请求时同样改用下划线分割。类似的,当不存在多级命名空间时,命名空间不应该含有下划线。
### 关于Action接口服务方法名
待请求的Action,应该是public访问级别的类方法,并且不能是[PhalApi/Api](https://github.com/phalapi/kernal/blob/master/src/Api.php)已经存在的方法。
### 一些示例
以下是一些综合的示例。
PhalApi 2.x 请求的s参数|对应的文件|执行的类方法
---|---|---
无|./src/app/Api/Site.php|Site::Index()
?s=Site.Index|./src/app/Api/Site.php|Site::index()
?s=Weibo.Login|./src/Api/Weibo.php|Weibo::login()
?s=User.Weibo.Login|./src/user/Api/Weibo.php|Weibo::login()
?s=Company_User.Third_Weibo.Login|./src/company_user/Api/Third/Weibo.php|Weibo::login()
上面示例中假设,已经在composer.json中配置有:
```
{
"autoload": {
"psr-4": {
"App\\": "src/app",
"User\\": "src/user",
"Company\\User\\": "src/company_user"
}
}
}
```
## 扩展:如何定制接口服务的传递方式?
虽然我们约定统一使用```?s=Namespace.Class.Action```的格式来传递接口服务名称,但如果项目有需要,也可以采用其他方式来传递。例如类似于Yii框架的请求格式:```?r=Namespace/Class/Action```。
如果需要定制传递接口服务名称的方式,可以重写[PhalApi\Request::getService()](https://github.com/phalapi/kernal/blob/master/src/Request.php)方法。以下是针对改用斜杠分割,并换用r参数名字的实现代码片段。
```php
// 文件 ./src/app/Common/Request.php
<?php
namespace App\Common;
class Request extends \PhalApi\Request {
public function getService() {
// 优先返回自定义格式的接口服务名称
$service = $this->get('r');
if (!empty($service)) {
$namespace = count(explode('/', $service)) == 2 ? 'App.' : '';
return $namespace . str_replace('/', '.', $service);
}
return parent::getService();
}
}
```
实现好自定义的请求类后,需要在项目的DI配置文件[./config/di.php](https://github.com/phalapi/phalapi/blob/master/config/di.php)进行注册。在最后的加上一行:
```php
$di->request = new App\Common\Request();
```
这时,便可以通过新的方式来进行接口服务的请求的了。即:
原来的方式|现在的方式
---|---
?s=Site.Index|?r=Site/Index
?s=App.Site.Index|?r=App/Site/Index
?s=Hello.World|?r=Hello/World
?s=App.Hello.World|?r=App/Hello/World
这里有几个注意事项:
+ 1、重写后的方法需要转换为原始的接口服务格式,即:Namespace.Class.Action,注意别遗漏命名空间。
+ 2、为保持兼容性,在取不到自定义的接口服务名称参数时,应该返回```parent::getService()```。
是不是觉得很好玩?可以立马亲自尝试一下哦。定制你最喜欢的请求方式。
## 在线接口文档
PhalApi提供一些非常实用而又贴心的功能特性,其中最具特色的就是自动生成的在线可视化文档。在线接口文档主要分为两大类,分别是:
+ 在线接口列表文档
+ 在线接口详情文档
当客户端不知道有哪些接口服务,或者需要查看某个接口服务的说明时,可借助此在线接口文档。访问在线接口列表文档的URL是:
```
http://dev.phalapi.net/docs.php
```
打开后,便可看到类似下面这样的在线接口文档。
![](http://7xiz2f.com1.z0.glb.clouddn.com/20170701174008_d80a8df4f918dc063163a9d730ceaf32)
此在线文档是实时生成的,可根据接口源代码以及注释自动生成。当有新增接口服务时,刷新后便可立即看到效果。通过在接口列表文档,可点击进入相应的接口详情文档页面。
> 温馨提示:如果打开在线文档,未显示任何接口服务,请确保服务环境是否已关闭PHP的opcache缓存。
### 如何生成离线文档?
上面在线的接口文档,也可以一键生成离线版的HTML文档,方便传阅,离线查看。
当需要生成离线文档时,可以在终端,执行以下命令:
```bash
phalapi$ php ./public/docs.php
Usage:
生成展开版: php ./public/docs.php expand
生成折叠版: php ./public/docs.php fold
脚本执行完毕!离线文档保存路径为:/path/to/phalapi/public/docs
```
执行后,可以看到类似上面的提示和结果输出。再查看生成的离线文档,可以看到类似有:
```bash
phalapi$ tree ./public/docs
./public/docs
├── App.Examples_CURD.Delete.html
├── App.Examples_CURD.Get.html
├── App.Examples_CURD.GetList.html
├── App.Examples_CURD.Insert.html
├── App.Examples_CURD.Update.html
├── App.Examples_Upload.Go.html
├── App.Site.Index.html
└── index.html
```
最后,可以在页面访问此离线版文档,如访问链接:
```
http://dev.phalapi.net/docs/index.html
```
#### 也可以将此docs目录打包,在本地打开访问查看。