设计正确的 REST URI
我有一个 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 动词来执行诸如验证之类的自定义操作。
提前致谢!
问候, 阿南德
I have a Java component which scans through a set of folders (input/processing/output) and returns the list of files in JSON format.
The REST URL for the same is:
GET http://<baseurl>/files/<foldername>
Now, I need to perform certain actions on each of the files, like validate, process, delete, etc. I'm not sure of the best way to design the REST URLs for these actions.
Since its a direct file manipulation, I don't have any unique identifier for the files, except their paths. So I'm not sure if the following is a good URL:
POST http://<baseurl>/file/validate?path=<filepath>
Edit: I would have ideally liked to use something like /file/fileId/validate. But the only unique id for files is its path, and I don't think I can use that as part of the URL itself.
And finally, I'm not sure which HTTP verb to use for such custom actions like validate.
Thanks in advance!
Regards,
Anand
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您实现像 http:///file/validate?path 这样的路由时,您会在资源中对操作进行编码在对资源服务进行建模时,这不是预期的效果。
您可以对读取操作执行以下操作
GET http://api.example.com/files 将返回所有文件作为 URL 引用,例如
GET http://api.example .com/files/path/to/first 将返回验证结果文件(我使用 JSON 来提高可读性)
这是简单的只读部分。现在进行写入操作:
删除http://api.example .com/files/path/to/first 当然会删除文件
对文件处理进行建模是困难的部分。但您可以将其建模为顶级资源。这样:
POST http://api.example.com/FileOperation?operation=somethingweird将创建一个虚拟文件处理资源并执行 URL 参数“operation”给出的操作。将这些文件操作建模为资源使您能够异步执行操作并返回一个结果,该结果提供有关操作过程等的附加信息。
您可以查看 Amazon S3 REST API 了解更多示例关于如何建模资源的灵感。我强烈推荐阅读RESTful Web Services
When you implement a route like http:///file/validate?path you encode the action in your resource that's not a desired effect when modelling a resource service.
You could do the following for read operations
GET http://api.example.com/files will return all files as URL reference such as
GET http://api.example.com/files/path/to/first will return validation results for the file (I'm using JSON for readability)
That was the simple read only part. Now to the write operations:
DELETE http://api.example.com/files/path/to/first will of course delete the file
Modelling the file processing is the hard part. But you could model that as top level resource. So that:
POST http://api.example.com/FileOperation?operation=somethingweird will create a virtual file processing resource and execute the operation given by the URL parameter 'operation'. Modelling these file operations as resources gives you the possibility to perform the operations asynchronous and return a result that gives additional information about the process of the operation and so on.
You can take a look at Amazon S3 REST API for additional examples and inspiration on how to model resources. I can highly recommend to read RESTful Web Services
它不是。
/file/validate
不描述资源,它描述操作。这意味着它是功能性的,而不是 RESTful 的。哦,是的,你可以!而您应该确实这样做。除了最后的
validate
部分;这无论如何都不是资源,因此不应成为路径的一部分。相反,客户端应该向文件资源发布一条消息,要求其验证自身。幸运的是,POST 允许您向文件发送消息并接收返回消息;它非常适合此类事情(除非有一个现有的动词可以使用,无论是在标准 HTTP 还是 WebDAV 等扩展之一中)。POST,要执行的操作由 POST 到资源的消息内容确定。当自定义“执行非标准操作”操作无法映射到 GET、PUT 或 DELETE 时,它们始终会映射到 POST。 (唉,聪明的 POST 并不是很容易被发现,因此会导致 HATEOAS 原则出现问题,但这仍然比违反基本的 REST 原则要好。)
It's not.
/file/validate
doesn't describe a resource, it describes an action. That means it is functional, not RESTful.Oh yes you can! And you should do exactly that. Except for that final
validate
part; that is not a resource in any way, and so should not be part of the path. Instead, clients should POST a message to the file resource asking it to validate itself. Luckily, POST allows you to send a message to the file as well as receive one back; it's ideal for this sort of thing (unless there's an existing verb to use instead, whether in standard HTTP or one of the extensions such as WebDAV).POST, with the action to perform determined by the content of the message that was POSTed to the resource. Custom “do something non-standard” actions are always mapped to POST when they can't be mapped to GET, PUT or DELETE. (Alas, a clever POST is not hugely discoverable and so causes problems for the HATEOAS principle, but that's still better than violating basic REST principles.)
REST 需要一个统一的接口,这在 HTTP 中意味着将自己限制为 GET、PUT、POST、DELETE、HEAD 等。
以 RESTful 方式检查每个文件的有效性的一种方法是将有效性检查视为不执行以下操作的操作:对文件执行,但作为其本身的资源:
这可能返回一个简单的 True/False,或者可能返回特定约束违规的列表。 file-id 可以是文件名、整数文件号、URL 编码的路径,或者可能是未编码的路径,例如:
另一种方法是询问无效文件的列表:
还有一种方法是防止无效文件文件首先会被添加到您的服务中,即当您的服务处理包含错误数据的 PUT 请求时:
它会以 HTTP 400(错误请求)拒绝该请求。 400 响应的正文可能包含有关特定错误的信息。
更新:要删除文件,您当然会使用标准 HTTP REST 动词:
要“处理”文件,这是否会从上传的文件创建一个新文件(资源)?例如,Flickr 根据您上传的每个图像文件创建多个不同的图像文件,每个图像文件的大小都不同。在这种情况下,您可以 PUT 一个输入文件,然后通过 GET-ing 相应的输出文件来触发处理:
如果处理不是近乎瞬时的,您可以异步生成输出文件:每次将新的输入文件 PUT 到Web 服务,Web 服务启动一个异步活动,最终导致创建输出文件。
REST requires a uniform interface, which in HTTP means limiting yourself to GET, PUT, POST, DELETE, HEAD, etc.
One way you can check on each file's validity in a RESTful way is to think of the validity check not as an action to perform on the file, but as a resource in its own right:
This could return a simple True/False, or perhaps a list of the specific constraint violations. The file-id could be a file name, an integer file number, a URL-encoded path, or perhaps an unencoded path like:
Another approach would be to ask for a list of the invalid files:
And still another would be to prevent invalid files from being added to your service in the first place, ie, when your service processes a PUT request with bad data:
it rejects it with an HTTP 400 (Bad Request). The body of the 400 response could contain information on the specific error.
Update: To delete a file you would of course use the standard HTTP REST verb:
To 'process' a file, does this create a new file (resource) from one that was uploaded? For example Flickr creates several different image files from each one you upload, each with a different size. In this case you could PUT an input file and then trigger the processing by GET-ing the corresponding output file:
If the processing isn't near-instantaneous, you could generate the output files asynchronously: every time a new input file is PUT into the web service, the web service starts up an asynchronous activity that eventually results in the output file being created.