【问题标题】:REST sub-entitiesREST 子实体
【发布时间】:2014-03-28 14:53:38
【问题描述】:

更新子实体的正确的 RESTful URL 结构是什么?

例如,我有一个 Question 实体。一个问题可以有很多答案。答案不仅仅是一个字符串,它们还有一个用户、pubDate 等。

创建 Question 实体的 URL 如下:

/questions/create

为特定问题创建答案的正确格式是什么?可能是这样的:

/questions/{questionId}/answers/create

或者他们应该有自己的专用路线,例如:

/answers/create?questionId={questionId}

感谢你们提供的任何帮助!

【问题讨论】:

    标签: node.js rest routing restful-url


    【解决方案1】:

    与普遍看法相反,REST 并不是真正的 URL 结构。事实上,应该只有一个“人类可读”的 URL,其余的都是由 HATEOAS 发现的。

    此外,不应有任何“用于创建问题的 URL”。应该有一个(或多个)问题容器,当您在那里发布时,会创建新实体。同样,一旦你有了问题 URL(在创建时返回,客户端不应该知道它有什么“结构”),你可以在那里做新的 POST 来创建答案。

    在您的示例中,一旦您执行任何所需的身份验证,对“根”URL 的 GET 可以返回包含所有所需容器的“主”资源:

    GET /api/
    => { "questions":"/api/questions/", .... }
    
    GET /api/questions/
    => [{"name":"firstone", "href":"/api/questions/11"}, 
        {"name":"final", "href":"/api/questions/43"}]
    
    GET /api/questions/101
    => {
        "name":"firstone", 
        "href":"/api/questions/11", 
        "text":"2+2", 
        "answers":[
            {"key":"A", "text":"23", "href":"/api/answers/15"},
            {"key":"B", "text":"3", "href":"/api/answers/34"},
            {"key":"C", "text":"4", "href":"/api/answers/7"}
        ]
    }
    

    添加一个新问题:

    POST /api/questions/   {"name":"onemore", "text":"2^2"}
    => 201 Location: /api/questions/45   
    data: {"name":"onemore", "text":"2^2", "href":"/api/questions/45"}
    
    GET /api/questions/45
    => {"name":"onemore", "text":"2^2", "href":"/api/questions/45"}
    

    添加答案:

    POST /api/questions/45    {"key":"A", "text":"4.5"}
    => 201 Location: /api/answers/56
    data: {"key":"A", "text":"4.5", "href":"/api/answers/56", "question":"/api/questions/45"}
    

    修改答案文本:

    PUT /api/answers/56   {"key":"A", "text":"4.8"}
    => 200
    data: {"key":"A", "text":"4.5", "href":"/api/answers/56", "question":"/api/questions/45"}
    

    当然,这有很多变体,尤其是当您 GET 容器时返回了多少“深度”信息。在这个例子中,当你得到一个问题时,会有一个答案列表。在一个极端,它可能只是一个 URL 列表,客户端必须获取每个 URL,在另一个极端,它可能是每个 URL 的全部数据,因此您只需一个请求即可获得所需的一切。

    通常,您必须为每个容器选择一个平衡点,可能有一些“基本”字段可以从第一个请求中获得,而其他字段可能会延迟。

    【讨论】:

    • 感谢有关使用 HTTP 动词的提示。所以你建议我发布到 /questions/{questionId} 来为问题创建答案?这对我来说似乎不是很有表现力,但也许我错过了 REST 的意义?这会比使用 PUT 来更新问题更可取吗? ** 我在您更新答案之前发布了此内容,让我阅读一下,看看它是否回答了我的问题
    • 太好了,感谢您提供更多详细信息。我仍然不完全相信 /api/questions/45 的 POST 是创建答案的一种非常有表现力的方式。例如,如果一个问题可以创建多个子实体怎么办?
    • 不要过多考虑 URL,考虑资源。一些资源是容器,要创建新资源,您 POST 到容器,服务器以新 URL 响应。更新您 PUT 到其 URL 的现有资源。如果一个问题可以有不止一种相关实体,也许它不应该是一个容器本身,但是当你得到它时,你会找到容器的 URL。 GET /api/questions/101 => {...., "answers":"/api/questions/101/answers/", "hints":"/api/questions/101/hints/", ....} 之类的东西,然后你可以 POST 到 answers 容器来添加一个新容器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 2017-05-10
    相关资源
    最近更新 更多