2.9. 内部调用
这个包的主要用途就是在 API 内部执行请求。它允许你在可用的 API 基础上构建你的应用。内部请求也可以返回原始数据,而不是原始响应对象,这意味着你可以获得与之相关的所有语法糖。
我们需要构建一个分发器实例来发起内部请求。
$dispatcher = app('Dingo\Api\Dispatcher');
我们现在可以用标准的 HTTP 进行内部请求.
Route::get('/', function () use ($dispatcher) {
$users = $dispatcher->get('api/users');
return View::make('index')->with('users', $users);
});
如果你在控制器中使用 Dingo\Api\Routing\Helpers
这个 trait
,可以用 $api
这个属性进行内部请求。
use Dingo\Api\Routing\Helpers;
class HomeController extends Controller
{
use Helpers;
public function index()
{
$users = $this->api->get('users');
return view('index')->with('users', $users);
}
}
发送数据
$dispatcher->with(['name' => 'Jason', 'location' => 'Australia'])->post('users');
或者你可以将数据作为第二个参数添加到 post
方法(也包括其他的 HTTP 动词,不只是 post
)
$dispatcher->post('users', ['name' => 'Jason', 'location' => 'Australia']);
指向特定的 API 版本
$dispatcher->version('v2')->get('users');
指向特定的域名
$dispatcher->on('api.example.com')->get('users');
上传附件
DingoAPI 支持多种上传附件的方法。 你可以传递一个 Symfony\Component\HttpFoundation\File\UploadedFile
实例数组, 当你向 API 上传附件时,这个非常方便。
$dispatcher->attach(Input::files())->post('photos');
或者你可以传递一个文件路径的数组,数组的 key 应该是文件的标识。
$dispatcher->attach(['photo' => 'photos/me.jpg'])->post('photos');
或者你可以传一个和文件路径相关的元数据数组。根据具体情况,这种方式会比上述方法会更准确,因为依赖包不需要运行计算 mime 类型和文件大小。
$dispatcher->attach([
'photo' => [
'path' => 'photos/me.jpg',
'mime' => 'image/jpeg',
'size' => '49430'
]
])->post('photos');
你也可以按需混合使用以上的这些方式。
发送 JSON 数据
$data = ['name' => 'bill', 'password' => 12345];
$dispatcher->json($data)->post('users');
如果 $data
是一个数组它将被自动编码。这个请求的 Content-Type
将被设置为 application/json
。
模拟认证用户
如果你的 API 端点需要认证,你可以在内部模拟一个给定的用户。例如,用户使用 Laravel 的身份验证登录到应用,你可以取得用户,然后模拟用户发起内部请求。
$dispatcher->be(auth()->user())->get('posts');
任何后续的请求都将被视为是同一用户。只是为给定的用户单个请求认证,你可以使用 once
方法。
$dispatcher->be(auth()->user())->once()->get('posts');
获取原始返回对象
所有的内部请求都会预先转换和格式化数据。例如,你可在内部接收到 API 从端点返回的一个 Eloquent 集合。 如果你需要返回原始对象,你只需要在调用方法前加上 raw
方法 。
$response = $dispatcher->raw()->get('users');
异常处理
在执行内部请求时,端点中抛出的任何异常都将被再次抛出,让你能够手动捕获。
public function store()
{
throw new Symfony\Component\HttpKernel\Exception\ConflictHttpException('We got a conflict!');
}
如果想在内部调用上述端点,那么我们需要捕获抛出的异常。
try {
app('Dingo\Api\Dispatcher')->with($payload)->post('users');
} catch (Symfony\Component\HttpKernel\Exception\ConflictHttpException $e) {
// 在这里做点啥,比方返回一个错误
}
这个包在返回错误响应时会抛出 Dingo\Api\Exception\InternalHttpException
异常,如果你使用 response
生成器构建返回错误,那么需要捕获这个异常。
public function show($id)
{
return $this->response->errorNotFound('Could not find the user.');
}
当在内部调用时我们需要捕获这个异常。
try {
app('Dingo\Api\Dispatcher')->get('users/1');
} catch (Dingo\Api\Exception\InternalHttpException $e) {
// 我们可以在这里获取响应,检查错误码或响应主体
$response = $e->getResponse();
}