查询字符串与筛选条件的资源路径 [英] Query String vs Resource Path for Filtering Criteria

查看:162
本文介绍了查询字符串与筛选条件的资源路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景



我有2个资源:课程教授



A 课程具有以下属性:




  • id

  • 主题

  • semester_id


  • 部分

  • professor_id



A 教授具有以下属性:




  • id

  • 教师

  • super_user

  • first_name

  • last_name



所以,你可以说课程有一位教授而一位教授可能有很多课程。



如果我想得到所有课程课程或所有教授我可以: GET / api / courses GET / api /教授






困惑



我的困惑是当我想要得到某教授教授的所有课程。



我可以使用以下任何一种方法:




  • GET / API /教授/:prof_id /课程

  • GET / API /课程professor_id =:prof_id



我不知道应该使用哪个。






当前解决方案



目前,我正在使用后者的增强形式。我的理由是,如果我想添加过滤/排序标准,它更具可扩展性。



我实际上是在编码/嵌入JSON字符串到查询参数中。所以,一个(解码的)例子可能是:

  GET / api / courses?where = {professor_id:teacher45,年份:2016}& order = {attr:topic,sort:asc} 

上面的请求将检索教授在2016年提供的Professor_id所教授的所有课程(根据主题标题按升序ASCII顺序排序)。



<我从未见过有人这样做过,所以我想知道我是不是做了些蠢事。






结束问题



是否有使用的标准做法查询字符串与过滤条件的资源路径?过去做过什么更大的API?是否可以接受或鼓励同时使用两种范例(使两个端点可用)?如果我确实应该使用第二范式,除了编码JSON之外,还有更好的组织方法吗?有没有人在他们的查询字符串中看到过使用JSON的另一个公共API?






编辑为基于意见的较少。 (见评论)

解决方案

正如之前的评论中已经解释的那样,REST并不关心链接的实际形式标识一个唯一的资源除非是 RESTful的约束或超文本传输​​协议(HTTP)本身是违反。



关于使用查询或路径(甚至矩阵)参数完全取决于您。还有时使用何种只是个人喜好没有固定的规则



我喜欢使用查询参数,特别是当值是可选的并且不需要像JAX-RS这样的大量框架时,即允许定义默认值。查询参数通常说来避免响应缓存然而其更是一个都市传奇然后实话,虽然某些实现可能仍然会省略对包含查询字符串的URI进行缓存的响应。



如果参数定义类似特定flavor属性的内容(即汽车颜色)我更喜欢将它们放入矩阵参数中。它们也可以出现在URI的中间,即 / api / professors; hair = gray / courses 可以返回由头发颜色为灰色的教授持有的所有资源。 / p>

路径参数是应用程序在我理解的意义上满足请求所需的必需参数,否则不会在服务端首先调用相应的方法处理程序。通常这是一些资源标识符,如表行ID,分配给特定实体的UUID。



关于描述关系,我通常从1的1部分开始:关系。如果我面对一个m:n的关系,就像你的教授 - cources一样,我通常从可能存在的实体开始,而不是更容易。教授仍然是教授,即使他没有任何讲座(在一个特定的术语中)。作为一门课程,如果没有教授可用,我会把教授放在cources之前,尽管在REST资源方面仍然是优秀的顶级资源。



因此,我会更改您的查询

  GET / api / courses ?where = {professor_id:teacher45,年份:2016}& order = {attr:topic,sort:asc} 

类似于:

  GET / api / professor / teacher45 / courses; year = 2016?sort = asc& onField = topic 

我稍微改变了字段的语义作为年份属性可能更适合课程而不是教授资源,因为教授已经通过教授身份缩减为单一资源。然而,课程应限于仅包括2016年举办的课程。由于排序是可选的并且可能具有指定的默认值,因此这是我放入查询参数部分的完美候选。要排序的字段与排序本身有关,因此也属于查询参数。我把年份放入矩阵参数中,因为这是课程本身的某种特性,比如汽车的颜色或汽车的制造年份。



但正如之前已经解释的那样,这是相当自以为是的,可能与您或其他人的观点不一致。


Background

I have 2 resources: courses and professors.

A course has the following attributes:

  • id
  • topic
  • semester_id
  • year
  • section
  • professor_id

A professor has the the following attributes:

  • id
  • faculty
  • super_user
  • first_name
  • last_name

So, you can say that a course has one professor and a professor may have many courses.

If I want to get all courses or all professors I can: GET /api/courses or GET /api/professors respectively.


Quandary

My quandary comes when I want to get all courses that a certain professor teaches.

I could use either of the following:

  • GET /api/professors/:prof_id/courses
  • GET /api/courses?professor_id=:prof_id

I'm not sure which to use though.


Current solution

Currently, I'm using an augmented form of the latter. My reasoning is that it is more scale-able if I want to add in filtering/sorting criteria.

I'm actually encoding/embedding JSON strings into the query parameters. So, a (decoded) example might be:

GET /api/courses?where={professor_id: "teacher45", year: 2016}&order={attr: "topic", sort: "asc"}

The request above would retrieve all courses that were (or are currently being) taught by the professor with the provided professor_id in the year 2016, sorted according to topic title in ascending ASCII order.

I've never seen anyone do it this way though, so I wonder if I'm doing something stupid.


Closing Questions

Is there a standard practice for using the query string vs the resource path for filtering criteria? What have some larger API's done in the past? Is it acceptable, or encouraged to use use both paradigms at the same time (make both endpoints available)? If I should indeed be using the second paradigm, is there a better organization method I could use besides encoding JSON? Has anyone seen another public API using JSON in their query strings?


Edited to be less opinion based. (See comments)

解决方案

As already explained in a previous comment, REST doesn't care much about the actual form of the link that identifies a unique resource unless either the RESTful constraints or the hypertext transfer protocol (HTTP) itself is violated.

Regarding the use of query or path (or even matrix) parameters is completely up to you. There is no fixed rule when to use what but just individual preferences.

I like to use query parameters especially when the value is optional and not required as plenty of frameworks like JAX-RS i.e. allow to define default values therefore. Query parameters are often said to avoid caching of responses which however is more an urban legend then the truth, though certain implementations might still omit responses from being cached for an URI containing query strings.

If the parameter defines something like a specific flavor property (i.e. car color) I prefer to put them into a matrix parameter. They can also appear within the middle of the URI i.e. /api/professors;hair=grey/courses could return all cources which are held by professors whose hair color is grey.

Path parameters are compulsory arguments that the application requires to fulfill the request in my sense of understanding otherwise the respective method handler will not be invoked on the service side in first place. Usually this are some resource identifiers like table-row IDs ore UUIDs assigned to a specific entity.

In regards to depicting relationships I usually start with the 1 part of a 1:n relationship. If I face a m:n relationship, like in your case with professors - cources, I usually start with the entity that may exist without the other more easily. A professor is still a professor even though he does not hold any lectures (in a specific term). As a course wont be a course if no professor is available I'd put professors before cources, though in regards to REST cources are fine top-level resources nonetheless.

I therefore would change your query

GET /api/courses?where={professor_id: "teacher45", year: 2016}&order={attr: "topic", sort: "asc"}

to something like:

GET /api/professors/teacher45/courses;year=2016?sort=asc&onField=topic

I changed the semantics of your fields slightly as the year property is probably better suited on the courses rather then the professors resource as the professor is already reduced to a single resource via the professors id. The courses however should be limited to only include those that where held in 2016. As the sorting is rather optional and may have a default value specified, this is a perfect candidate for me to put into the query parameter section. The field to sort on is related to the sorting itself and therefore also belongs to the query parameters. I've put the year into a matrix parameter as this is a certain property of the course itself, like the color of a car or the year the car was manufactured.

But as already explained previously, this is rather opinionated and may not match with your or an other folks perspective.

这篇关于查询字符串与筛选条件的资源路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆