DEV Community

Discussion on: RESTful API, Updating Object by Action Query Parameter

 
rouilj profile image
John P. Rouillard

Because attributes are part of the same object, having a single Class with several methods to
update each attribute seems more flexible to me. And it offers us the possibility of having a single
endpoint exposed to perform several different update operations on the same object.

Your making it too difficult. If you have to update multiple attributes of an object,
perform a GET /users/1 to receive the following JSON:

{
            "address": "admin@localhost",
            "alternate_addresses": null,
            "organisation": null,
            "phone": "603-555-4423",
            "realname": "The Admin",
            "roles": "Admin,Agent",
            "theme": "red1",
            "timezone": "America/New_York",
            "username": "admin"
}
Enter fullscreen mode Exit fullscreen mode

If you want to update multiple fields, you perform a PUT on /users/1 with the changed data and proper headers (if-match for example):

{
            "address": "admin@newhost",
            "alternate_addresses": null,
            "organisation": "I am an organization",
            "phone": "603-444-1111",
            "realname": "The NEW Admin",
            "roles": "Admin",
            "theme": "blue2",
            "timezone": "America/New_York",
            "username": "admin"
}
Enter fullscreen mode Exit fullscreen mode

This changes all the attributes atomically. Either all changes happen (status code 200) or none of the changes happen (any status code in 400 or 500 range).

Now the tricky part is what happens when you have multiple objects that have to be modified atomically?
Consider transferring money from one account to another. I update the balance for /account/4 by perfomring a GET, subtracting 20 dollars from the balance and PUTting the new data. Then I make a deposit in /account/5 by updating the balance by 20 dollars.

What happens if the second transaction fails? How do you make that transaction atomic?
One way I have seen discussed is to use a transaction endpoint. You POST:

{ "amount": 20 }

to /account/transaction?from=4&to=5. (Yes the query parameters can be passed as part of the POST data, but you like query params so....) This returns a transaction ID (lets say 5) for the transaction
and performs the balance updates on the back end. Now you can GET /account/transaction/5 and see:

{
  "from_account": 4,
  "to_account": 5,
  "amount": 20,
  "status": "pending"
}
Enter fullscreen mode Exit fullscreen mode

or status complete when the transaction has completed. This is a very simple example that fits (or can be made to fit) into the REST architecture.

As I said I am not a REST purist, but quite a lot can be accomplished within the REST architecture.

Using the architecture also means that if I can retrieve the data (with GET) I also know how to change the data using PUT (simply put what I received back with changes). I also know how to create an entry by posting something that looks like what GET returns to /users.

With a query param, every one of those parameters "?email=", "?change_email", "?t=email" has to be documented and taught to the user. They can't use the standard REST methods and they can't autodiscover or guess what will work.