搜索的过滤与排序
搜索在RESTful API里是用GET方法实现的,URI一般是某个对象,可以是单个也可以是列表。以微博搜索为例,如果不加任何条件,其URI一般是这样的:
/api/weibo
/api/weibo/6
但往往还需要限制一下搜索条件,例如评论数大于某个数,或者含有什么关键字,如果是搜索微博列表,也可能加上对日期作升序或降序排序的要求。这些附加条件,是作为query param附加在http请求里的。例如:
- GET /weibo?deleted=true - 得到所有标记为删除的微博
- GET /weibo?sort=-create-date - 按照创建日期反序排序得到微博列表
- GET /weibo?sort=comment-count,-create-date - 先按微博评论数再按创建日期反序排序得到微博列表
- GET /weibo?keyword=xxx - 得到包含关键字xxx的微博列表
- GET /weibo?keyword=xxx&deleted=true&sort=comment-count,-create-date - 搜索关键字包含xxx的标记为删除的微博,按照评论数再按创建日期反序排序得到微博列表
确定了搜索对象,例如weibo,那么在服务器端我们就知道需要查找哪个表,或者需要连接哪几个表。where后面的条件则根据附上的参数动态选择。order by后面的属性则根据sort后面的参数添加,带-号的代表降序,很容易翻译成sql语言。
我们还可以选择返回哪些属性,或者不返回哪些属性。例如:
- GET /weibo?fields=id,subject - 得到微博列表,每个微博里的字段只有id和subject两个,其他的都排除了。
- GET /weibo?fields-exclude=id,subject - 得到微博列表,每个微博里的id和subject被排除了,输出其他的字段。
这些参数就是select后面的列信息。
由于RESTful API的资源是面向对象的,我们往往是对某一个对象作查找,如果在查找里需要附带其他资源对象的信息,也可以在query param里添加,用embed字段作为key。例如:
- GET /weibo?embed=owner.id,owner.name - 得到微博列表,每个微博里的信息里加入这个微博的所有者的id和name两个属性。
这些属性也是跟在select后面的,只要参数名与数据库的表名能一一对应即可。由于存在嵌入的对象属性,在数据库查找上往往便需要多表连接。
上一讲说的翻页的页数和每页的数据项数也是作为query param传给服务器的。
常用的查询
上面说的对搜索的过滤和排序是通用的,根据传入的参数而动态构造sql语句。而对于某些特别常用的查询,例如新浪微博里的最热微博top10,则可以用专用的名字代替,例如:
- GET /weibo/top10
不太能归类的操作
http是面向资源的,RESTful API是基于http的,其操作也是针对某个资源对象进行的,操作的类型则用http方法表达,例如PUT,POST,PATCH,DELETE,GET。然而,有些操作不是那么容易归类为上述的http方法,例如给微博点赞。我们可以把点赞操作理解成修改微博对象,按照这个定义是应该用PUT或PATCH方法。但是一般意义上我们说的对微博的修改是指编辑微博的文本内容。因此,有必要把点赞这个操作独立出来,会更加方便,意义也更加清晰。例如:
- PUT /weibo/12/like - 给某个微博点赞
- DELETE /weibo/12/like - 删除某个微博的赞
常用的status code
- 200 OK - 正常返回,用于GET, PUT, PATCH的这些正常操作。
- 201 Created - 用于POST创建对象正常返回。
- 204 No Content - 用于DELETE,成功操作但没啥返回的。
- 304 Not Modified - 有Cache,表示没改过。
- 400 Bad Request - 指请求里面有些参数不对。
- 401 Unauthorized - 没有登录
- 403 Forbidden - 登录了但是没有授权访问某个资源
- 404 Not Found - 资源不存在
- 405 Method Not Allowed - 登录了但是不允许做某个操作
- 410 Gone - 表示资源不再提供了,用来做老版本提示用的
- 415 Unsupported Media Type - 請求的Centent Type不對
- 422 Unprocessable Entity - 一般用于validation校验
- 429 Too Many Requests - 请求太快太多,达到限制
http提供了很多的status code。但在RESTful API里常用的就这几个。我们可以根据业务需求对不同的request返回相匹配的状态码。方法就是上一讲提到的构造Response对象返回以及异常处理。
JAX-RS怎样接收客户端的参数
RESTful API的核心是URI,HTTP方法以及数据传输格式,在第一讲详细讲过。http header也十分重要,在第二讲讲过。除此之外,服务器与客户端的交互往往需要传递一些参数,例如对象id,需要更新的整个对象以及上面提到的query param等。这些参数的传递都是通过注解实现的。下面介绍一下常用的参数注解。
PathParam
|
|
需要删除某条微博,此时URI里必定含有该微博的id信息,可以用@PathParam注解从URI里提取参数。
QueryParam
|
|
翻页信息用query param传递,用@QueryParam注解可以提取。
FormParam
|
|
用POST请求提交的表格,其表单内容可以用@FormParam获取。
MatrixParam
|
|
上述的request请求URI是/books/2011;author=mkyong;country=malaysia。@MatirxParam可以提取用;分隔的一组key/value对。
HeaderParam和CookieParam
@HeaderParam和@CookieParam注解都是提取header或者cookie里某个key的value。像@HeaderParam(“Referer”)和@CookieParam(“customerId”)等,非常简单。
获取HttpServletRequest和HttpServletResponse
JAX-RS是基于servlet实现的。其每个资源方法都可以提取相应请求的HttpServletRequest和HttpServletResponse对象。利用这两个对象,我们可以在资源方法内构造Response对象,也可以修改header和cookie。这两个对象都可以用@Context注解获取。上面的一些例子也有体现。
payload对象
http request的payload对象在网络中是以json或xml的格式传输的,只要JAX-RS里能保证其反序列化,那么在参数列表里直接用相应的POJO对象类名和实体名表示即可。例如:
|
|
上面的MessageDTO对象便是http request的payload对象。