shashi
shashi

Reputation: 4696

Use a single POST request to update to create two objects Bad API design?

Consider the scenario, an unknown unauthenticated user is looking at the list of nerddinners and then goes to a particular dinner, enter his name and email and clicks "Attend". This should result in two things. Create the user and create the DinnerAttendRequest for that user. The user also has a property called FavProgLanguage which is set to the prog language property of the dinner which he wants to attend.

Assuming it is a single page javascript app which talks to an API, there are two approaches which come to mind.

1) On the client, set the users FavProgLanguage and then POST to /user with name, email and favproglanguage to create the user. Use the created UserId and POST to /DinnerAttendRequest with DinnerId and UserId to create DinnerAttendRequest.

2) POST to /somename with Name, email and dinnerId and then use dinnerId at server to populate favproglanguage of user. create user and then use userid to create DinnerAttendRequest

The first approach seems more natural/RESTful, however if the logic of computing the favproglanguage is a bit complex, all the api consumers would have to implement that logic and with the second approach that code is written just once on the server.

Which is a better approach? Is the second approach RESTful?

Upvotes: 1

Views: 150

Answers (1)

Mark Jones
Mark Jones

Reputation: 12184

Your 1st design would place the burden of logic, workflow and the fav lang decision, upon the client, this would make handling the user creation and reservation a single transaction difficult and something that a client app would need to orchestrate. Your fav lang logic sounds like an important business rule that again should ideally sit at the server for re-use...

Why don't you look at having some resources like so:

  1. Dinner e.g. { "name", "date", etc. }
  2. Booking e.g. { "user" { NESTED USER RESOURCE }, "bookingStatus", etc. }
  3. User e.g. { "email", "name", "fav lang", etc.}

Some example urls

  1. /dinners/{uid}
  2. /dinners/{uid}/bookings
  3. /users/{uid}

Basically I would POST a Booking resource containing a nested User resource to the dinner bookings url and run the logic for checking is a user exists, creating if needed and updating their fav lang in a transaction.

So to create a booking I would POST a Booking Resource:

{
    "user": {
        "email": "[email protected]",
        "name": "name"
    },
    "bookingStatus": "requested"
}

To /dinners/{uid}/bookings

And expect a 201 created response with a response like this:

{
    "uid": "4564654",
    "user": {
        "uid": "1234564",
        "email": "[email protected]",
        "name": "name",
        "favLang": "C#"
    },
    "bookingStatus": "booked"
}

Obviously the properties are largely just for example but hopefully this demonstrates some of the concepts and shows that a single POST can be considered RESTful...

Upvotes: 3

Related Questions