Create single and multiple resources using restful HTTP

前端 未结 5 928
时光取名叫无心
时光取名叫无心 2021-02-07 00:21

In my API server I have this route defined:

POST /categories

To create one category you do:

POST /categories {\"name\": \"Books         


        
相关标签:
5条回答
  • 2021-02-07 00:41

    Actually this is still a hot topic till today, But simplify things I almost of the time say there is always a batter suited scenario for each practice. Eg: 1. If you are receiving the likes from a post you don't need the bulk as in case there is only one like per comment. 2. If you are receiving favorites comment the bulk can fit well by considering someone reviewing the comment he reads and check box all of his favorites and send it once.

    Again this is based on my experience working with Restful API, and but currently for the sake of multi tasking and others things, me and my colleague we found our selves doing the bulk all the time in most MIS(Management Information System) we do. This is because modern days web app and mobile app that can do a lot of work and send the final results to the back-end, this way the back-end has little job to do as long as the data received don't violate the business logic.

    0 讨论(0)
  • 2021-02-07 00:43

    There's nothing wrong with creating multiple resources at once with POST (just don't try it with PUT). It's not "un-REST-ful", especially if you create a representation for the bulk operation itself. I suggest you create an index resource at the same time you create the individual resources, and return a "303 See Other" to it. That index representation would then contain links to all of the created resources (and possibly error information if any of them failed).

    POST /categories/uploads/
    [{"name": "Books"}, {"name": "Games"}]
    
        303 See Other
        Location: /categories/uploads/321/
    

    (actually, now that I think about it, 201 might be better than 303)

    GET /categories/uploads/321/
    
        200 OK
        Content-Type: application/json
    
        [{"name": "Books", "link": "/categories/Books/"},
         {"name": "Games", "error": "The 'Games' category already exists."}]
    
    0 讨论(0)
  • 2021-02-07 00:44

    There's nothing particularly wrong with having a bulk operation that you POST to, to activate (it'll be non-idempotent so POST is the right verb) but there are some caveats:

    • You're making multiple resources, so you need to respond with multiple URLs. This means you can't use the redirect pattern: you'll have to send a list of URLs back in some form.

    • You have a problem in that bulk operations are often not very discoverable. Discoverability is one of the most important things about RESTfulness, as it means that someone can come along and figure out how to write a client without lots of help from the server author.

    • Dealing with partial failures when you've got bulk operations remains problematic. It's a problem with any other paradigm too (I've watched people tie themselves in knots over this when working with extensions to SOAP) so it isn't a surprise, but unless you can guarantee that all the creations will work, you're going to have to work out what happens when you make one resource and fail to make the second. (Also, if the bulk request wanted a third one done, would you go on and try that?)

    The simplest approach is just to support one create per request; that's a much easier pattern to get right and is better understood all round.

    0 讨论(0)
  • 2021-02-07 00:47

    In your case I would also go the /bulk resource way. But the pattern I would suggest is the following and from my understanding the most natural: Work with the 202 Accepted status code.

    The idea of a bulk request is that the server should not be forced to answer immediately as this would mean client needs to wait until it's bulk request completed.

    Here is the pattern:

    POST /bulk [{"name": "Books"}, {"name": "Games"}]
    202 Accepted | Location: /bulk/processing/status/resourceId
    
    GET /bulk/processing/status/resourceId
    entry = "REST in peace" | completed | 0 errors | /categories/category/resourceId
    entry = "Walking dead" | processing | 0 errors ->
    

    So, the client POSTs the bulk information to the server. The server just accepts them with a 202 which gives no guarantee about the processing state at the time of response. But the server also provides the link to a status resource. Here the client can have a look on each of the created resources and the processing state. When finished the client can access the resource via the given link. Error cases can be identified by the client and erroneous data might be resend by a PUT on the completed resource.

    Finally, a good advice I am usually following is: Whenever you hit a resource in your design that cannot be mapped on a HTTP feature it is probably because of a missing resource.

    0 讨论(0)
  • 2021-02-07 01:05

    In true REST, you should probably POST this in multiple separate calls. The reason is that each one will result in a new representation. How would you expect to get that back otherwise.

    Each post should return the resultant resource location:

    POST -> New Resource Location
    POST -> New Resource Location
    ...
    

    However, if you need a bulk, then create a bulk. Be dogmatic where possible, but if not, pragmatism gets the job done. If you get too hung up on dogmatism, then you never get anything done.

    Here is a similar question

    Here is one that suggests HTTP Pipelining to make this more efficient

    0 讨论(0)
提交回复
热议问题