dingo/api自定义返回接口格式

最近看了教主的restful api系列视频,群里有很多人提了个问题,如何自定义实现返回值,官方文档里有说明,但是不是很具体,这里再废话一下

参照https://github.com/dingo/api/wiki/Transformers">官方文档

return $this->collection($users, new UserTransformer, function ($resource, $fractal) {

    $fractal->setSerializer(new CustomSerializer);

});

这里的CustomSerializer,其实就是自定义的一个类

具体实现如下:

namespace App\Serializeruse League\Fractal\Serializer\ArraySerializer;

class CustomSerializer extends ArraySerializer{    

    public function collection($resourceKey, array $data)     

    {         

        return ['custom-data-name' => $data];     

    }    

    public function item($resourceKey, array $data)     

    {         

        return ['custom-data-name' => $data];     

    } 

} <br></br>
sodasix

叫地主…

snail

@sodasix 我抢

Cribug

3分

旭LLTP

“message”: "Argument 3 passed to Dingo\Api\Http\Response\Factory::collection() must be of the type array, object given, called

gg444108853 回复 旭LLTP

一样的问题 不知道怎么办!

JellyBool 回复 gg444108853

还是把代码贴和报错信息出来看看吧?

gg444108853 回复 JellyBool
{
  "message": "Argument 1 passed to Dingo\\Api\\Http\\Response\\Factory::collection() must be an instance of Illuminate\\Support\\Collection, instance of App\\User given, called in /var/www/html/api/app/Api/Controllers/AuthController.php on line 104 and defined",
  "status_code": 500
}
gg444108853 回复 JellyBool
public function getAuthenticatedUser()
{
    try {

        if (! $user = JWTAuth::parseToken()->authenticate()) {
            return response()->json(['user_not_found'], 404);
        }

    } catch (TokenExpiredException $e) {

        return response()->json(['token_expired'], $e->getStatusCode());

    } catch (TokenInvalidException $e) {

        return response()->json(['token_invalid'], $e->getStatusCode());

    } catch (JWTException $e) {

        return response()->json(['token_absent'], $e->getStatusCode());

    }
    // the token is valid and we have found the user via the sub claim
    return $this->response->collection($user, new UserTransformer, [], function ($resource, $fractal) {
        $fractal->setSerializer(new CustomSerializer);

    });
    //return response()->json(compact('user'));
}
JellyBool 回复 gg444108853

你确定这就是你写的代码?你的 $user 是怎么来的 ?报错信息在:

Api/Controllers/AuthController.php on line 104

猜测的原因是你的 $user 是使用了 find 或者 findOrFail 等方法查找的吧?把查找 $user 的语句放出来看看

gg444108853 回复 JellyBool
public function index()
{
    $data = User::all();
    //return $this->response->collection($data4,new LessonTransformer());
    return $this->response->collection($data, new UserTransformer(), [], function ($resource, $fractal) {
        $fractal->setSerializer(new CustomSerializer);
    });
}
JellyBool 回复 gg444108853

这是 Api/Controllers/AuthController.php 的 104 行么?话说你的 $user 是怎么来的

gg444108853 回复 JellyBool
public function getAuthenticatedUser()
{
    try {

        if (! $user = JWTAuth::parseToken()->authenticate()) {
            return response()->json(['user_not_found'], 404);
        }

    } catch (TokenExpiredException $e) {

        return response()->json(['token_expired'], $e->getStatusCode());

    } catch (TokenInvalidException $e) {

        return response()->json(['token_invalid'], $e->getStatusCode());

    } catch (JWTException $e) {

        return response()->json(['token_absent'], $e->getStatusCode());

    }
    // the token is valid and we have found the user via the sub claim
    return $this->response->collection($user, new UserTransformer, [], function ($resource, $fractal) {
        $fractal->setSerializer(new CustomSerializer);
    });
    //return response()->json(compact('user'));
}

就是获取user信息那个函数,然后就是提示$fractal那行有错误

colder
return $this->collection($users, new UserTransformer, [], function ($resource, $fractal) {

	$fractal->setSerializer(new CustomSerializer);

});
colder

根据楼主的提示,成功的实现了自定义返回结果

{
  "message": "success",
  "status_code": 200,
  "data": [
    {
      "no": "88888888",
      "mobile": "13923458160",
      "id_no": "99999999",
      "name": "ColderWinter",
      "nick": "Wohoho",
      "sex": "男",
      "signature": "This is ColderWinter"
    }
  ]
}
wenber 回复 colder

hi,请教一下.我在api中错误操作全部使用异常来返回.只有成功时候会选择$this->response()->item or collection来做成功返回.所以用这种方式来实现在成功响应中增加message和code时,是需要在每个接口成功响应的时候都要加入一个自定义格式的回调吗?

colder 回复 wenber

怎么回复不了?

colder 回复 wenber

教主,回复好慢啊

colder 回复 wenber

回复不了代码,我是说一下吧。因为时间过去的有点久了,不太记得了。我做了一个Trait,在BaseController里引入,这个Trait叫Responder,封装了Dingo API的响应数据,加入status_code和message

trait Responder
{
use Helpers;

public function responseCollection(Collection $collection, TransformerAbstract $transformer)
{
    return $this->response->collection($collection, $transformer, [], function ($resource, Manager $fractal) {
        $fractal->setSerializer(new CustomSerializer());
    });
}

public function responseItem($item, TransformerAbstract $transformer)
{
    return $this->response->item($item, $transformer, [], function ($resource, Manager $fractal) {
        $fractal->setSerializer(new CustomSerializer());
    });
}

public function responsePaginate(Paginator $paginator, TransformerAbstract $transformer)
{
    return $this->response->paginator($paginator, $transformer, [], function ($resource, Manager $fractal) {
        $fractal->setSerializer(new CustomSerializer());
    });
}

public function responseData(array $data)
{
    return Response::json([
        'message' => '操作成功',
        'status_code' => 200,
        'data' => $data
    ], 200);
}

public function responseSuccess($message='操作成功')
{
    return Response::json([
        'message' => $message,
        'status_code' => 200
    ], 200);
}

public function responseFailed($message='操作失败')
{
    return Response::json([
        'message' => $message,
        'status_code' => 400
    ], 400);
}

public function responseError($message='未知错误')
{
    return Response::json([
        'message' => $message,
        'status_code' => 500
    ], 500);
}

}

wenber 回复 colder

是把dingo api 的helper Trait又封装了一次吗?我刚刚用监听api的ResponseWasMorphed事件实现了.因为我是想在api调用成功的时候加入这两个字段.所以在监听成判断响应中有data的字段的时候加入.
if (isset($event->content[‘data’])) {
$event->response->setContent(
[
‘message’ => ‘success’,
‘status_code’ => 200,
‘data’ => $event->content[‘data’],
]
);
}

colder 回复 wenber

class CustomSerializer extends ArraySerializer
{
public function collection($resourceKey, array $data)
{
return [
‘message’ => ‘操作成功’,
‘status_code’ => 200,
‘data’ => $data
];
}

public function item($resourceKey, array $data)
{
    return [
        'message' => '操作成功',
        'status_code' => 200,
        'data' => $data
    ];
}

}

wenber 回复 colder

我是在ide复制的代码,直接粘贴上来的.回复后不能显示.刷新下就可以了

colder 回复 wenber

然后在控制器里直接用return this>responseData(this->responseData(trips);

colder 回复 wenber

我也是醉了,没办法整体粘贴,整体粘贴发表不了

wenber 回复 colder

明白了.万分感谢!!!

colder 回复 wenber

祝你顺利。能做点贡献是我的荣幸

JellyBool 回复 colder

怎么整体粘贴?出现什么问题

colder 回复 JellyBool

貌似是有PHPDoc的原因

JellyBool 回复 colder

纳尼,这么奇葩。。。还真没遇到过。我看看 log

colder 回复 JellyBool

清空下

colder 回复 JellyBool

果然是啊,我把PHPDoc拿掉就能回复了,但是会像下面这样呢

JellyBool 回复 colder

有 PHPDoc 的时候是报什么错?或者有什么提示?

colder 回复 JellyBool

木有提示,就是一直正在发表……

JellyBool 回复 colder

果然是,如果是 DocBlock 开始的话,貌似 HtmlPurifier 全部过滤了,内容就变成空的了。。。

colder 回复 JellyBool
<?php

namespace App\Serializer;

use League\Fractal\Serializer\ArraySerializer;


class CustomSerializer extends ArraySerializer
{
    /**
     * 重新封装Dingo API返回的data,加入status_code和message
     *
     * @param string $resourceKey
     * @param array $data
     * @return array
     */
    public function collection($resourceKey, array $data)
    {
        return [
            'message' => '操作成功',
            'status_code' => 200,
            'data' => $data
        ];
    }

    public function item($resourceKey, array $data)
    {
        return [
            'message' => '操作成功',
            'status_code' => 200,
            'data' => $data
        ];
    }
}
colder 回复 JellyBool

清空下

JellyBool 回复 colder

但是使用了 markdown 格式的话,就没有问题

colder 回复 JellyBool

原来如此,那我用MD重新回复下

JellyBool 回复 colder

恩,你前面的回复是这样开始的吧:


/**
 * Created by PhpStorm.
 * User: ColderWinter
 * Date: 2016/6/25
 * Time: 14:39
 * Reference: https://laravist.com/discussion/586
 */
colder 回复 JellyBool

是滴是滴就是这样滴六个字

天山网艾克

稿件分页 怎么实现, 我用paginate 出现 错误

”Argument 1 passed to Dingo\\Api\\Http\\Response\\Factory::collection() must be an instance of Illuminate\\Support\\Collection, instance of Illuminate\\Pagination\\LengthAwarePaginator given”

怎么解决

天山网艾克
$articles =  Article::with('getCategory')->where('category_id',$category_id)->paginate(1);
        return $this->collection($articles, new ArticleTransformer(), function ($resource, $fractal) {
            $fractal->setSerializer(new ArticleSerializer());
        });
天山网艾克
public function index($category_id =0)
    {
        $articles =  Article::with('getCategory')->where('category_id',$category_id)->paginate(1);
        return $this->collection($articles, new ArticleTransformer(), function ($resource, $fractal) {
            $fractal->setSerializer(new ArticleSerializer());
        });
    }
snail 回复 天山网艾克
public function index($category_id =0)
    {
        $articles =  Article::with('getCategory')->where('category_id',$category_id)->paginate(1);
        return $this->paginator($articles, new ArticleTransformer(), function ($resource, $fractal) {
            $fractal->setSerializer(new ArticleSerializer());
        });
    }
假如_丶

CustomSerializer类

return [
            'data'      => [
                'data' => $data,
                'meta' => 1      // 想做到变量,自定义传值....因为现在就一个data的数据,这个怎么做到啊。。。
            ],
            'info'      => '操作成功',
            'status'    => 1,
        ];
baoniu 回复 假如_丶

刚遇到这问题, 我也想知道~ 7个月还没有解决^^

baoniu 回复 假如_丶

我这样弄了,暂时解决掉了,希望有更好的方法:
public function responseItem($item, TransformerAbstract $transformer, $status_code = 200, $message = null)
{
return this>response>item(this->response->item(item, transformer,[],function(transformer, [], function (resource, Manager fractal)use(fractal) use (status_code, $message) {
fractal>setSerializer(newCustomSerializer(fractal->setSerializer(new CustomSerializer(status_code, $message));
});
}

status_code = $status_code; $this->message = $message; } public function collection($resourceKey, array $data) { return [ 'data' => $data, 'status_code' => $this->status_code, 'message' => $this->message ? $this->message : '', ]; } public function item($resourceKey, array $data) { return [ 'data' => $data, 'status_code' => $this->status_code, 'message' => $this->message ? $this->message : '', ]; } }
假如_丶 回复 baoniu

直接自定义了 - -,要不太浪费时间了…