Responses 响应

Dingo API 主要在于处理接受客户端的request请求,以及按规范返回数据给客户端,API 默认会将返回数据以JSON的格式返回,我们也可以定义多样式的返回格式,主要取决于你自己(其中Transformer就是给返回数据做处理用的),还有前面说的fractal这个东东,Transformer和fractal的关联和区别在哪里,可以先看下[龙爷]发的这个连接:
http://fractal.thephpleague.com/simple-example/

最简单的数据返回可以从你的controllers中使用一个数组或者是一个对象来返回,并不是每一个对象都能够正确的返回,所以要确保它们实现了ArrayObject或者Illuminate\Support\Contracts\ArrayableInterface接口:怎么实现???

class UserController
{
    public function index()
    {
        return User::all();
    }
}

上面这样写默认返回的是json数组,如果dd(User::all()); 数据类型是对象的集合,而 return User::all(); 会在返回的时候自动格式化。

[{"id": 2,
"name": "zhoujiping",
"email": "[email protected]",
"created_at": "2016-05-31 03:38:48",
"updated_at": "2016-05-31 03:40:22"
},
{"id": 3,
"name": "kuker",
"email": "[email protected]",
"created_at": "2016-05-31 03:39:59",
"updated_at": "2016-05-31 03:39:59"
}
]
// return 会自动将collection 转成json数组

下面是返回一个对象

class UserController
{
    public function index()
    {
        return User::first();
    }
}

下面是得到的数据:

{"id": 2,
"name": "zhoujiping",
"email": "[email protected]",
"created_at": "2016-05-31 03:38:48",
"updated_at": "2016-05-31 03:40:22"
}

我们dd(User::first()); 得到的是一个User对象,使用return, 则会自动将对象转成json格式。 (这个return成json, laravel自己默认就是这样的啊)

Dingo API会自动将响应格式化为JSON格式并设置Content-Type头为application/json。

Response Builder 响应构建器

下面的汇成一句话,就是:让你使用Dingo的response对象

response builder 提供了一套平滑的接口,可以很简单的就构建出更加符合需要的数据返回。response builder 通常和转化器(transformer)一起使用,transformer的作用如下:

我们可以通过return User::all()直接返回数据,但是更多的时候,我们需要对数据库提取的数据进行过滤或者转化才会返回,或者我们不想直接暴露数据库表字段,比如说要返回成下面这样,就可以用transformer

{
"user_id": 2,
"user_name": "zhoujiping",
"user_email": "[email protected]",
// "created_at": "2016-05-31 03:38:48", 
// "updated_at": "2016-05-31 03:40:22"
}

要想使用Dingo的 response, 必须在控制器中调用Dingo\Api\Routing\Helpers这个trait, 因为每一个api的controller都需要用到这个trait, 所以我们可以建立一个BaseController,用这个BaseController引入trait,然后别的controller来继承这个BaseController

use Dingo\Api\Routing\Helpers;
use Illuminate\Routing\Controller;

class BaseController extends Controller
{
    use Helpers;
}

现在可以定义一个继承自该控制器的控制器,在这些控制器中可以通过$response属性来访问响应构建器。

Responses 响应_第1张图片
namespace App\Api\Controllers; 才行,上面我写错了
Responses 响应_第2张图片
namespace App\Api\Controllers; 才行,图上我写错了

返回集合数组

class UsersController extends BaseController
{
    public function index()
    {
        $user = User::all();

        return $this->response->array($user->toArray());
    }
}

返回数据如下:

[{"id": 2,
"name": "zhoujiping",
"email": "[email protected]",
"created_at": "2016-05-31 03:38:48",
"updated_at": "2016-05-31 03:40:22"
},
{"id": 3,
"name": "kuker",
"email": "[email protected]",
"created_at": "2016-05-31 03:39:59",
"updated_at": "2016-05-31 03:39:59"
}]

返回单个对象,并在返回的时候经过转化器转化transformer

response->item($user, new UserTransformer);
    }
}

UserTransformer 看下面的图

Responses 响应_第3张图片
Paste_Image.png

返回的数据

{
    "data": {
        "user_id": 2,
        "User_name": "zhoujiping",
        "User_email": "[email protected]"
    }
}

返回对象集合,结合transformer

如果不需要用transformer处理,那就用上面的array返回就行

response->collection($users, new UserTransformer);
    }
}

返回的数据

{
    "data": [
        {
            "user_id": 2,
            "User_name": "zhoujiping",
            "User_email": "[email protected]"
        },
        {
            "user_id": 3,
            "User_name": "kuker",
            "User_email": "[email protected]"
        }
    ]
}

对于分页的返回

response->paginator($users, new UserTransformer);
    }
}

返回如下:

{
    "data": [
        {
            "user_id": 2,
            "User_name": "zhoujiping",
            "User_email": "[email protected]"
        }
    ],
    "meta": {
        "pagination": {
            "total": 2,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 2,
            "links": {
                "next": "http://blog-api.dev?page=2"
            }
        }
    }
}

Responding With No Content

这个搞不懂,真的是什么都没返回,连空都没有,dd($this->response->noContent()) 是一个Response 对象

return $this->response->noContent();

创建响应

return $this->response->created();

还可以将位置信息作为创建资源的第一个参数:

return $this->response->created($location);

返回空内容和创建响应,这两个不知道怎么用的???

内置的错误响应函数

// 常见的错误,用户自定义内容和错误码.
return $this->response->error('页面傻逼了,跑掉了', 404);

// A not found error with an optional message as the first parameter.
return $this->response->errorNotFound();

// A bad request error with an optional message as the first parameter.
return $this->response->errorBadRequest();

// A forbidden error with an optional message as the first parameter.
return $this->response->errorForbidden();

// An internal error with an optional message as the first parameter.
return $this->response->errorInternal();

// An unauthorized error with an optional message as the first parameter.
return $this->response->errorUnauthorized();

添加额外的响应头

return $this->response->item($user, new UserTransformer)->withHeader('zjp', 'zhoujiping');

看下头部的数据

Cache-Control →private, must-revalidate
Connection →close
Content-Type →application/json
Date →Tue, 31 May 2016 08:05:05 GMT
ETag →"87b076ffa048592f60b5b0729ce0452d"
Server →Apache/2.4.18 (Unix) PHP/5.6.19
X-Powered-By →PHP/5.6.19
zjp →zhoujiping

添加元数据

这个对于做SEO有点用

return $this->response->item($user, new UserTransformer)->addMeta('keywords', '周继平的博客, zhoujiping')->addMeta('description','我这里是描述');

看下返回的数据

{
    "data": {
        "user_id": 2,
        "User_name": "zhoujiping",
        "User_email": "[email protected]"
    },
    "meta": {
        "keywords": "周继平的博客, zhoujiping",
        "description": "我这里是描述"
    }
}

返回数据的时候,设定状态吗

我们之前返回的json数据,如果是成功的话,默认的status就是200,要设置的话,可以这样设置:

return $this->response->item($user, new UserTransformer)->addMeta('keywords', '周继平的博客, zhoujiping')->addMeta('description','我这里是描述')->setStatusCode(250);

看下数据

Responses 响应_第4张图片
Paste_Image.png

状态码不在数据中,而是在图片的右上角,什么情况???why ????

Morphing And Morphed Events

Dingo在返回数据前会先转化(morph)响应,关于数据返回的处理,我们现在已经灰常清楚了,先通过transformer进行数据的处理,然后通过我们在config中设置的format格式,进行格式化。

我们如果对于转化有自己的需求,可以通过ResponseWasMorphed事件 和ResponseIsMorphing事件来处理

演示一下,先在app/Listeners 中创建监听器

content['meta']['pagination'])) {
            $links = $event->content['meta']['pagination']['links'];

            $event->response->headers->set(
                'link',
                sprintf('<%s>; rel="next"', 
                    $links['next'])
            );
        }
    }
}

然后EventServiceProvider中注册监听

    protected $listen = [
        'Dingo\Api\Event\ResponseWasMorphed' => [
        'App\Listeners\AddPaginationLinksToResponse'
        ],
    ];

返回的数据

{
    "data": [
        {
            "user_id": 2,
            "User_name": "zhoujiping",
            "User_email": "[email protected]"
        }
    ],
    "meta": {
        "pagination": {
            "total": 2,
            "count": 1,
            "per_page": 1,
            "current_page": 1,
            "total_pages": 2,
            "links": {
                "next": "http://blog-api.dev?page=2"
            }
        }
    }
}

同时在头文件中也有

link →; rel="next"

你可能感兴趣的:(Responses 响应)