我一直在开发一套针对移动应用程序公开的其他API。我正在遵循Laravel项目开发的存储库模式。如何实现演示器和转换器,以便在我的所有API集合中格式化常量JSON输出?
例如,我有以下控制器用于登录
public function authenticate()
{
$request = Request::all();
try {
// If authenticated, issue JWT token
//Showing a dummy response
return $token;
} catch (ValidatorException $e) {
return Response::json([
'error' =>true,
'message' =>$e->getMessageBag()
]);
}
}
现在,变压器和演示者在哪里?我知道两者都用于通过转换db对象来格式化输出,并生成格式化的JSON,以便它在我的API中保持一致。
dingo API和fractal甚至框架(L5 repository)都没有提供详细的文档,我也找不到相关的教程。
我为另一个 API创建了以下演示者和变换器,它提供了产品列表
namespace App\Api\V1\Transformers;
use App\Entities\Product;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract {
public function transform(\Product $product)
{
return [
'id' => (int) $product->products_id
];
}
}
演示
<?php
namespace App\Api\V1\Presenters;
use App\Api\V1\Transformers\ProductTransformer;
use Prettus\Repository\Presenter\FractalPresenter;
/**
* Class ProductPresenter
*
* @package namespace App\Presenters;
*/
class ProductPresenter extends FractalPresenter
{
/**
* Transformer
*
* @return \League\Fractal\TransformerAbstract
*/
public function getTransformer()
{
return new UserTransformer();
}
}
如何在控制器中设置演示者并回复?试图
$this->repository->setPresenter("App\\Presenter\\PostPresenter");
但它似乎没有用,而且文档没有显示完整的步骤。
答案 0 :(得分:1)
我有同样的问题,这就是我如何使用变压器的dingo
控制器:
public function update(Request $request)
{
$bus = new CommandBus([
$this->commandHandlerMiddleware
]);
$agency = $bus->handle(
new UpdateAgencyCommand($request->user()->getId(), $request->route('id'), $request->only('name'))
);
return $this->response->item($agency, new AgencyTransformer());
}
变压器:
class AgencyTransformer extends TransformerAbstract
{
public function transform(AgencyEntity $agencyEntity)
{
return [
'id' => (int) $agencyEntity->getId(),
'name' => $agencyEntity->getName(),
];
}
}
这就是我处理错误的方法:
throw new UpdateResourceFailedException('Could not update agency.', $this->agencyUpdateValidator->errors());
答案 1 :(得分:1)
我现在也在这里看到你的类似问题。请在此处查看我对您的其他问题的回答:https://stackoverflow.com/a/34430595/429719。
从我推导出的另一个问题你使用的是Dingo
,所以将它用作结构化的响应类。确保您的控制器从Dingo
延伸,然后您可以以结构化的方式返回项目和集合:
return $this->response->item($user, new UserTransformer);
return $this->response->collection($users, new UserTransformer);
如果您想要一个很好的错误处理,请在此处查找文档:https://github.com/dingo/api/wiki/Errors-And-Error-Responses
基本上,您可以抛出任何核心异常或一些自定义Dingo
异常。 Dingo层将捕获它们并返回结构化的JSON响应。
根据Dingo文档:
throw new Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException('Nope, no entry today!');
将生成:
{
"message": "Nope, no entry today!",
"status_code": 403
}
答案 2 :(得分:0)
分形在此完整记录:http://fractal.thephpleague.com/ 我经常从Phil Sturgeon那里读到一本很好的书https://leanpub.com/build-apis-you-wont-hate你可以找到github https://github.com/philsturgeon/build-apis-you-wont-hate中提供的大部分书籍代码。你可以在那里找到非常好的Fractal例子。
Tranformers正在以一致的json格式转换对象,以便所有端点为每个实体返回相同的内容。
这个
答案 3 :(得分:0)
您可以尝试使用,[Midresapi]:https://github.com/oktorino/midresapi。这将返回一致的成功或失败响应,在 laravel 7 和 8 中工作,处理验证响应,处理 500 响应:
$users=\App\User::latest()->limit(2)->get();
return response($users);
#or
return fractal()
->collection($users)
->transformWith(new \App\Transformers\UserTransformer)
->toArray();
回复:
{
"status_code": 200,
"success": true,
"message": "ok",
"data": [
{
"username": "dany",
"email": "jancuk@sabarbanget.com"
},
{
"username": "scc-client-5150",
"email": "dancuk@gmail.com"
}
]
}