0

I need to do rest transactions with a WebAPI. I've tried to figure out how to pass complex request parameters into the body of the request and also respect Rest standards like.

The GET method is a safe method (or nullipotent), meaning that calling it produces no side-effects: retrieving or accessing a record does not change it. The PUT and DELETE methods are idempotent, meaning that the state of the system exposed by the API is unchanged no matter how many times more than once the same request is repeated. POST is not idempotent.

Here are the standards I've come up with where q is a query parameter and b is a complex body parameter:

Get         Get(q)      Get(q,b)
HttpGet     HttpGet     HttpPut

Create      Create(b)   Create(q,b)
HttpPost    HttpPost    HttpPost

                        Update(q,b)
                        HttpPut

            Delete(q)   Delete(q,b)
            HttpDelete  HttpPut

Does this pattern really respect the REST standards?

Maly Lemire
  • 267
  • 2
  • 10
  • What do you mean by `rest transactions` exactly? Some distributed transactions handled by RESTful services or some simple [shopping card](https://stackoverflow.com/questions/147207/transactions-in-rest) like scenario? If you have to modify multiple resources atomically in a single transaction `PATCH` is probably more suited. – Roman Vottner Sep 29 '17 at 11:49
  • I have complex scenarios where business logic must be keep in the Web API to be used by multiple clients mvc, wpf, windows services, etc. I sometimes need to get an entity but that get requires a complex model as parameter. I also sometimes need to delete and use a complex parameter for business logic. From a performance point of view and to prevent difference in business logic I cannot reproduce it on each client using simple shopping cart rest scenario. – Maly Lemire Sep 29 '17 at 13:08
  • This does not really describe what kind of transactions you are needing. Its more of a justification to not use a RESTful approach due to performance considerations, which is fine. Note that REST isn't a simple Web interface to database queries though from what you described you litterally are looking for a direct mapping of queries and results to a Web interface, why not expose the database directly to these clients in first place? – Roman Vottner Sep 29 '17 at 13:53
  • Some clients cannot be connected directly to the database. Phones for example. And I'm actually using Entity Framework on the web api. – Maly Lemire Sep 29 '17 at 16:00
  • You still haven't defined what you define as `rest transaction`. REST itself doesn't specify anything like that. At best its underlying protocol does. REST focus is on resources and their current state but less on transaction spawned over multipe resources as this would require to keep some transaction state on the server. As an explicit resource representation isn't performant enough for your needs REST via HTTP is maybe not the right style to design your API in that scenario. You are of course free to redefine HTTP methods or implement new ones, though this will break other clients for sure – Roman Vottner Sep 29 '17 at 16:39

1 Answers1

0

REST does not really have a standard, it's more a style really.

As long as you have some resources and stick to the Verbs then you are true enough to REST I'd say.

Passing complex objects in the body of the request has nothing to do with REST. Imagine you want to create an entity Employee.

you have a URL which is /employees or /employee, it's up to you if you want plural or not, but whatever you decide, be consistent.

You issue a POST to /employee let's say and in the Body you have all the details required to create one entity. Your body data will be a JSON representation of whatever complexity you have.

If you want to update an object you issue a PUT.

From what you currently have it is hard to say what you want.

Let's look at Create(b).

If by that you mean something like this, then yes that is good :

[POST]
Public IHttpActionResult Create([FromBody]b)
{
    //some code
    //I personally like to return the id of the created entity
    // but sometimes you might want to return the entire entity, 
    //should you need that or only a few fields, all options are valid and 
    //depend on your circumstances
    return OK(id);
    or 
    return Ok(createdEntity)
}

when you create your URLs make sure you don't have verbs in them

stuff like /createEmployee is not ok for example

a PUT request to /employee/45/address/1

that is ok in my book to update a specific address of a specific employee

or a PUT to /employee/45 this is also ok to update that employee

GET to /employee returns all employees GET to /employee/45 returns only one matching the id

Andrei Dragotoniu
  • 6,155
  • 3
  • 18
  • 32
  • While REST is not a stadard it requires that the implementation adheres to the underlying protocol (HTTP in most cases) and thus should follow its rules. Furthermore, REST doesn't care how an URI is built up as the semantics are not contained in the URI itself but in the relation name the URI is used hence it doesn't matter if the URI ends with `createEmployee` or not in theory. If you create a new resource you should return the URI of that resource in a Location header (not necessarily the body). PUT replaces the current representation with the received body which has the effect of an update – Roman Vottner Sep 29 '17 at 11:05
  • I was trying to respect these standards : The GET method is a safe method (or nullipotent), meaning that calling it produces no side-effects: retrieving or accessing a record does not change it. The PUT and DELETE methods are idempotent, meaning that the state of the system exposed by the API is unchanged no matter how many times more than once the same request is repeated. – Maly Lemire Sep 29 '17 at 13:15