【问题标题】:Consistent REST API Response in Laravel+DingoLaravel+Dingo 中一致的 REST API 响应
【发布时间】:2016-03-22 09:05:59
【问题描述】:

我一直在开发一组用于移动应用的 REST 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 和分形甚至框架 (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");

但它似乎不起作用,文档没有显示完整的步骤。

  1. 在上面的示例中,如何为可以在我的 API 中使用的错误响应创建一个模板,以及如何将我的错误异常传递给它?
  2. 似乎presenter 和transformer 可用于将数据库对象 转换为可展示的JSON,而不是其他任何东西。对吗?
  3. 如何使用 Presenter 和 Transformer 来获得成功响应和错误响应?通过将异常而不是 DB 对象传递给转换器?

【问题讨论】:

    标签: php json rest laravel dingo-api


    【解决方案1】:

    Fractal 已在此处完整记录:http://fractal.thephpleague.com/ 我经常从 Phil Sturgeon https://leanpub.com/build-apis-you-wont-hate 那里读到一本很棒的书,您可以在 github https://github.com/philsturgeon/build-apis-you-wont-hate 中找到大部分可用的书籍代码。您可以在那里找到非常好的分形示例。

    1. 我会创建一个 Api 控制器并从我的控制器中扩展它。里面应该有所有的响应函数(respondWithError、respondWithArray 等)
    2. 转换器正在以一致的 json 格式转换对象,以便所有端点为每个实体返回相同的内容。

    3. 对此真的没有答案

    4. Fractal 文档中有足够多的示例。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,这就是我如何使用带有变压器的野狗

      控制器:

      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());
      

      【讨论】:

        【解决方案3】:

        我刚刚在这里也看到了您的类似问题。因此,请在此处查看我对您的其他问题的回答:https://stackoverflow.com/a/34430595/429719

        从我得出的另一个问题中,您正在使用Dingo,因此将其用作结构化响应类。确保您是从 Dingo 扩展的控制器,然后您可以以结构化方式返回项目和集合,例如:

        return $this-&gt;response-&gt;item($user, new UserTransformer);

        return $this-&gt;response-&gt;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
        }
        

        【讨论】:

        • return $this->response->item($user, new UserTransformer);实际上并没有改变我的回答。没有错误或其中显示任何内容。我只是得到没有任何转换的普通 json。
        【解决方案4】:

        您可以尝试使用,[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"
            }
          ]
        }
        

        【讨论】:

          猜你喜欢
          • 2016-09-28
          • 1970-01-01
          • 2016-07-22
          • 2016-03-07
          • 1970-01-01
          • 1970-01-01
          • 2016-02-29
          • 2014-08-24
          • 1970-01-01
          相关资源
          最近更新 更多