基于聚合数据的RESTful端点查询设计

时间:2016-04-19 18:41:20

标签: rest

假设我们有两个资源:人物,电影。

persons/123
{id: 123, firstName: "John", lastName:"Travolta"}

persons/124
{id: 124, firstName: "Uma", lastName: "Thurman"}

persons/125
{id: 125, firstName: "Bob", lastName: "Saget"}

persons/126
{id: 126, firstName: "Christopher", lastName: "Walken"}

persons/127
{id: 127, firstName: "Steve", lastName: "Buscemi"}


movies/1
{id: 1, name: "Pulp Fiction"}

movies/2
{id:2, name: "Reservoir Dogs"}

然后,为了将两者联系起来,我们有另一个资源:演员

GET cast-members?movie.name=Pulp%20Fiction
[
    {
        id: 502,
        movie: {id: 1, name: "Pulp Fiction"}
        actor: {id: 123, firstName: "John", lastName:"Travolta"},
        character: "Vincent Vega"
    },
    {
        id: 503,
        movie: {id: 1, name: "Pulp Fiction"}
        actor: {id: 124, firstName: "Uma", lastName: "Thurman"},
        character: "Mia Wallace"
    },
    {
        id: 504,
        movie: {id: 1, name: "Pulp Fiction"}
        actor: {id: 126, firstName: "Christopher", lastName: "Walken"},
        character: "Buddy Holly"
    },
    ...
]

如果我想看看Christopher Walken所有的电影,我知道我可以这样做:

GET cast-members?actor.id=125

如果我想看看两个 Uma Thurman和John Travolta都在演员阵容中的所有电影怎么办?这个端点是什么样的?

GET cast-members?actor.id=124&actor.id=125

不起作用。

我们返回演员身份,其中actor.id是124或125?

[
    {
        id: 587,
        movie: {id: 10, name: "Kill Bill"}, 
        // John's not in this movie
        actor: {id: 124, firstName: "Uma", lastName: "Thurman"},        
        character: "The Bride"
    },
    {
        id: 597,
        movie: {id: 11, name: "Saturday Night Fever"}, 
        // Uma's not in this movie
        actor: {id: 123, firstName: "John", lastName:"Travolta"},
        character: "Tony Manero"
    },
    ...
]

这不是我们想要的,因为我们必须在客户端加入电影(这是不可取的,因为这意味着我们必须在返回结果之前翻阅大量数据)

SQL查询将是:

SELECT Movie
FROM CastMember
WHERE Actor in (124, 125)
GROUP BY Movie
HAVING COUNT(DISTINCT Actor) = 2

有没有办法将此查询转换为使REST具有意义的内容?

1 个答案:

答案 0 :(得分:1)

问题可能是“演员”资源 - 它的建模是真正的资源而不是某种“合成”资源尚不清楚。并非关系数据库中的所有表都是资源。 ReSTful关系通常被建模为资源之间的链接,而不是资源本身。

您的资源细分核心是您已经

  • 电影

他们(可能)被分为集合

假设你构建了你的URI空间,以便你有

  • /电影
    • 电影集
  • /电影/ {ID}
    • 具有给定ID的个人电影
  • /人
    • 一群人,可能不仅仅是电影中的演员
  • /人/ {ID}
    • 具有给定身份的个人演员

如果要查找某人所在的所有电影,可以根据“演员”查询搜索电影资源。该查询可以采用多个值,因为说某个给定的电影有多个演员是完全合理的。

所以,如果你想找到所有电影中有ids 1234和5678的人都在你的查询中

GET /movie?actor=1234,5678

现在,您可以根据您的使用情况以几种不同的方式实现它。也许它只返回一个电影URI列表,你必须单独查询每一个,但这听起来不太好。或许,另一方面,它会返回所有匹配的完整电影文档的列表(标题,完整演员,年份,长度,故事大纲,评论等) - 这可能是很多数据,所以你可以添加一个{ {1}}参数...

page

也许你只想要与每部电影相关的一些细节 - 你可以为你的细节添加一个参数....

GET /movie?actor=1234,5678&page=2&pageSize=10

注意:到目前为止,不需要“人”资源。但是,GET /movie?actor=1234,5678&details=title,id,cast 查询中的响应文档将包含指向各个电影URI和人员URI的链接...

movies
相关问题