1

I have a api to let user add a book http://127.0.0.1/book
What if the user want to create 100 books at a time ?

I find some discuss here
LiorH said :

Although bulk operations (e.g. batch create) are essential in many systems,  
they are not formally addressed by the RESTful architecture style.

Is it a restful design suggestion??

I like post one item at one time
But my partner want create all at one time
I think create all at one time will have problem if some of them's format is valid,some of them are not
I want to make sure this

Community
  • 1
  • 1
user2492364
  • 6,543
  • 22
  • 77
  • 147

2 Answers2

3

I like the Thierry Templier's approach, as described in the article Implementing Bulk Updates within RESTful Services. I'll just summarize the main ideas here, adapted to your context. Nevertheless, I do recommend reading the full article:

Request

Commonly, the POST method is used to add a single element to the collection. So, we could have a resource that accepts both single element and collection of elements for its method. According to the input payload, the processing detects if a single or a bulk add must be done.

As a matter of fact, having another resource that uses an action name in resource path like /books/bulk isn’t really RESTful, so it’s not the right approach.

When creating a single element, we can have something like this:

POST /books
Content-Type: application/json
{
    "title": "The Lord of the Rings - The Fellowship of the Ring",
    "author": "J. R. R. Tolkien",
    (...)
}

And the following, in the case of a bulk operation:

POST /books
Content-Type: application/json
[
    {
        "title": "The Lord of the Rings - The Fellowship of the Ring",
        "author": "J. R. R. Tolkien",
        (...)
    },
    {
        "title": "The Lord of the Rings - The Two Towers",
        "author": "J. R. R. Tolkien",
        (...)
    },
    (...)
]

Response

When creating a single element, the response is quite straightforward and commonly contains two things:

  • A status code 201 (Created)
  • An header Location contained the URL of the newly created element
201 Created
Location: http://example.com/api/book/{id}

The Location header accepts one value and can be defined once within a response. That said, since the semantics of a POST method is up to the RESTful service designer, we can leverage the header Link to provide this hint, as described below:

201 Created
Link: <http://example.com/api/book/{id}>, <http://example.com/api/book/{id}>

Transaction

In a bulk operation, you can consider a transactional approach:

  • Everything works fine and all data is inserted
  • At least one element has validation errors and nothing is added
  • One or more insert fails and everything is rollbacked
422 Unprocessable Entity
Content-type: application/json
[
    {
        "index": 1,
        "messages": [
            {
                "title": "The title should at least have three characters."
             }
        ]
    },
    {
        "index": 1,
        "messages": [
            {
                "id": "The value of the field it isn't unique."
             }
        ]
    },
]

In the case of insertion errors:

500 Internal Server Error
Content-type: application/json
[
    {
        "index": 1,
        "messages": [
            "The book can't be added because of the error #22 (description)"
        ]
    },
    (...)
]

For non-transactional processing, the status code of the response will always be 200 and errors, if any, described in the response payload, as shown below:

200 OK
Content-type: application/json
[
    {
        "index": 1,
        "status": "error",
        "messages": [
            "The book can't be added because of the error #22 (description)"
        ]
    },
    {
        "index": 2,
        "status": "success",
        "auto-generated-id": "43"
    },
    (...)
]
Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
2

REST talks about exchanging representations of the things you care about. If you care about sets of books, then create a representation for that and allow clients to POST them.

The tricky part in these services always is the response, because the usual pattern is that after POSTing a resource, your response is or redirects to the newly created resource's URI.

However, nothing is keeping you to respond with a list of URIs, meaning that the result of POSTing a set of books is a set of created resources.

However, there one big caveat in this, which are the failure semantics. If only some of the books get created, what happens? Is it possible that only some of the books get created and then client has to deal with that? This is where things can get rather tricky, which is the reason why a lot of people try to avoid this. There's nothing fundamentally wrong with it, but it complicates the API quite a bit, and the performance gains may be smaller than one might think.

Is there a reason why you couldn't create the books one at a time? I'd recommend to make the API as simple as possible, unless you have compelling reasons to make it more complicated.

dret
  • 531
  • 3
  • 7