【问题标题】:Designing proper REST URIs设计正确的 REST URI
【发布时间】:2012-01-07 18:03:01
【问题描述】:

我有一个 Java 组件,它扫描一组文件夹(输入/处理/输出)并返回 JSON 格式的文件列表。

相同的 REST URL 是:

GET http://<baseurl>/files/<foldername>

现在,我需要对每个文件执行某些操作,例如验证、处理、删除等。我不确定为这些操作设计 REST URL 的最佳方式。 由于它是直接的文件操作,因此我没有文件的任何唯一标识符,除了它们的路径。所以我不确定以下是否是一个好的 URL:

POST http://<baseurl>/file/validate?path=<filepath>

编辑:理想情况下,我希望使用 /file/fileId/validate 之类的东西。但是文件的唯一唯一 ID 是它的路径,我认为我不能将它用作 URL 本身的一部分。

最后,我不确定将哪个 HTTP 动词用于验证等自定义操作。

提前致谢!

问候, 阿南德

【问题讨论】:

    标签: http url rest uri


    【解决方案1】:

    当您实现http:///file/validate?path 之类的路由时,您在资源中对操作进行编码,这在对资源服务进行建模时并不是预期的效果。

    您可以对读取操作

    执行以下操作

    GET http://api.example.com/files 将返回所有文件作为 URL 引用,例如

    http://api.example.com/files/path/to/first
    http://api.example.com/files/path/to/second
    ...
    

    GET http://api.example.com/files/path/to/first 将返回文件的验证结果(我使用 JSON 来提高可读性)

    {
       name : first,
       valid : true
    }
    

    那是简单的只读部分。现在到写操作

    DELETE http://api.example.com/files/path/to/first 当然会删除文件

    对文件处理进行建模是困难的部分。但是您可以将其建模为顶级资源。所以:

    POST http://api.example.com/FileOperation?operation=somethingweird 将创建一个虚拟文件处理资源并执行 URL 参数“操作”给出的操作。将这些文件操作建模为资源使您可以异步执行操作并返回一个结果,该结果提供有关操作过程等的附加信息。

    您可以查看Amazon S3 REST API 以获取有关如何对资源进行建模的其他示例和灵感。我强烈推荐阅读RESTful Web Services

    【讨论】:

      【解决方案2】:

      现在,我需要对每个文件执行某些操作,例如验证、处理、删除等。我不确定为这些操作设计 REST URL 的最佳方式。由于它是直接的文件操作,因此除了它们的路径之外,我没有任何唯一标识的文件。所以我不确定以下是否是一个好的 URL:POST http:///file/validate?path=

      不是。 /file/validate 没有描述资源,它描述了一个动作。这意味着它是功能性的,而不是 RESTful。

      编辑:理想情况下,我希望使用/file/fileId/validate 之类的东西。但是文件的唯一唯一 ID 是它的路径,我认为我不能将它用作 URL 本身的一部分。

      哦,是的,你可以!而你应该正是这样做的。除了最后的validate 部分;这绝不是一种资源,因此不应成为路径的一部分。相反,客户端应该向文件资源发布一条消息,要求它验证自己。幸运的是,POST 允许您向文件发送消息并接收回消息;它非常适合这类事情(除非有一个现有的动词可以代替,无论是在标准 HTTP 还是 WebDAV 等扩展之一中)。

      最后,我不确定要为验证等自定义操作使用哪个 HTTP 动词。

      POST,要执行的操作由发布到资源的消息的内容决定。当自定义的“做一些非标准的事情”动作不能映射到 GET、PUT 或 DELETE 时,它们总是映射到 POST。 (唉,一个聪明的 POST 并不是很容易被发现,因此会导致 HATEOAS 原则出现问题,但这仍然比违反基本 REST 原则要好。)

      【讨论】:

        【解决方案3】:

        REST 需要一个统一的接口,这在 HTTP 中意味着将自己限制为 GET、PUT、POST、DELETE、HEAD 等。

        您可以通过 RESTful 方式检查每个文件的有效性的一种方法是将有效性检查视为对文件执行的操作,而不是将其视为一种资源:

        GET /file/{file-id}/validity
        

        这可能会返回一个简单的 True/False,或者可能是特定约束违规的列表。 file-id 可以是一个文件名、一个整数文件号、一个 URL 编码的路径,或者可能是一个未编码的路径,例如:

        GET /file/bob/dir1/dir2/somefile/validity
        

        另一种方法是询问无效文件的列表:

        GET /file/invalid
        

        还有一个方法是首先防止将无效文件添加到您的服务中,即当您的服务处理带有错误数据的 PUT 请求时:

        PUT /file/{file-id}
        

        它使用 HTTP 400(错误请求)拒绝它。 400 响应的正文可能包含有关特定错误的信息。

        更新:要删除文件,您当然会使用标准的 HTTP REST 动词:

        DELETE /file/{file-id}
        

        要“处理”一个文件,这是否会从已上传的文件中创建一个新文件(资源)?例如,Flickr 会根据您上传的每个文件创建多个不同的图像文件,每个文件的大小都不同。在这种情况下,您可以 PUT 输入文件,然后通过 GET-ing 相应的输出文件来触发处理:

        PUT /file/input/{file-id}     
        GET /file/output/{file-id}
        

        如果处理不是近乎即时的,您可以异步生成输出文件:每次将新的输入文件放入 Web 服务时,Web 服务都会启动一个异步活动,最终导致输出文件已创建。

        【讨论】:

        • 根据 Fielding,您的第一句话是不正确的:“REST 风格并不表示限制方法集是一个理想的目标。[...] 特别是,REST 鼓励创建新的模糊操作的方法,特别是因为我们不想让常用方法承担所有逻辑的负担,即试图弄清楚特定操作是否适合 99.9% 的情况或其他占 0.1% 的情况之一。”来源:xent.com/pipermail/fork/2001-August/003191.html 话虽如此,我喜欢你将有效性本身作为一种资源的想法。
        • 此外,状态码 400 更多地用于服务器本身,例如 Apache,当它接收到格式错误的请求时,而不是当应用程序认为媒体类型格式错误时。那将是状态代码 422 Unprocessable Entity。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-19
        • 1970-01-01
        相关资源
        最近更新 更多