Craig
Craig

Reputation: 18694

Restful way to perform a data changing action

I'm trying to stay Resftful, and follow protocols. I have an "Organisation" domain object, and have the usual POST/GET/PUT/DELETE operations:

POST https://www.example.com/api/organisation saves a new org. GET https://www.example.com/api/organisation/{id} gets an org by it's ID etc

Something a user can do from the client side (Website, mobile, etc) is set their default organisation. On the database side, we're just setting a default flag against the org they want to be defaulted.

But the API side, I'm not sure how to do, and keep it within good practice. At the moment, I have a method in my code:

        [HttpPost]
        public async Task<IActionResult> SetDefaultOrganisation()

I am not sure how to expose that to the API.

https://www.example.com/api/organisation/setdefault/{id}

That doesn't seem right. I don't want to do a PATCH, as.. the api must describe whats happening. It's not an any-item-can-change.

Is https://www.example.com/api/organisation/{id}/setdefault a more acceptable option?

Upvotes: 0

Views: 35

Answers (2)

Ygalbel
Ygalbel

Reputation: 5519

One important point in restful endpoints is to be resource centric and not process centric.

That's mean if you have a verb (an action, like save or add) in you endpoint, you have a problem in your design.

In your question you wrote

Something a user can do from the client side (Website, mobile, etc) is set their default organisation

So from a resource point of view, the main resource here is the user.

With this point the endpoint can be like this (a POST or PUT)

/api/user/{userId}/orgranizations/default

And the body: { orgID : 1234}

Upvotes: 1

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57249

Restful way to perform a data changing action

In REST, the way we pass information to the web server is by editing the website.

This is normally done in one of two ways

  • We GET a representation of the resource, make edits to our copy, and then deliver the revised representation to the server
  • We fill in form, and deliver the representation of the form data to the server.

From the perspective of REST, these two patterns are the same ones that you use for editing any resource (that's the uniform interface constraint at work: our general purpose tools don't need to know anything about the meaning of the edits we are making).

Therefore, the design problem is to identify which resource (document) includes the representation of the information you want, and what representation (schema) you will use to communicate that change of information.

From the perspective of general purpose REST components, we don't care what the document is -- that's the server's problem; we only care about the string literal used to identify the document.

General purpose components also don't care about spelling conventions; /a472a51b-7e36-404b-a985-1fc79d1b7464 is a perfectly satisfactory identifier. What this degree of freedom means is that you can choose identifiers that are easy for human beings to understand, and identifiers that are easy for your implementation to route.

/api/organisation/{id}/setdefault

From the point of view of a general purpose components, this is fine. Human beings, however, a likely to object -- because this looks like it identifies an action, and what we really want is an identifier that tells us what the document is.

So that might be /api/organization/{id}, if somewhere in the document that describes the organization we have a list of users for whom this is the default organization.

But I think it would be more common to have something like /api/profiles/{userId}, where the profile document includes information about what the default organization is for each user.

If you needed a fine grain resource, then it might instead be something like /api/profiles/{userId}/defaultOrganization or even /api/defaultOrganizations/{userId}

(The ordering of path segments is something you decide upon based on how you want to take advantage of the relative references, as defined by RFC 3986).

Upvotes: 0

Related Questions