REST API - Add item as relational resource to another resource - rest

I have been wondering what would be the best approach when adding a resource that is linked to another resource.
I have two objects:
+ Employee: An employee for an IT company
+ Skill: The employee set of technology skills; for example, Java.
Someone can create an employee via REST with the following path:
POST: /employee
Though someone could create a Skill object by itself, similar to creating an Employee object, but it needs to be linked to an Employee, thus...
PATCH: /employee/{employeeId}/skill
This path will create a new Skill to the Employee object, but this is where I am wondering if I am doing something wrong.
Usually when you create a new resource, you use the POST verb, but at the same time I am also updating part of the Employee resource thus it acts like a PATCH verb. Plus, a POST verb should be free from any parameters like {employeeId}.
What would be the best approach / practice when documenting REST API with this scenario?

What would be the best approach / practice when documenting REST API with this scenario?
It may be worth reviewing Jim Webber's 2011 talk.; in short, if you are doing REST, then you are passing around documents -- the useful work performed on your domain model is a side effect of document manipulation.
If you are using PUT/PATCH, then you are fundamentally performing remote authoring -- which is to say, you are asking the server to accept your local copy of a document. And that's fine, even when the server, in accepting your edits, will also be changing its representation of other resources.
You could instead design your application domain protocol so that you are making remote edits to the employee document directly, or even POST-ing edits to that resource, which in turn could have side effects on a skill resource.
Remember, the first application designed using the REST architectural style was the World Wide Web; the most common media-type for defining domain application protocols was HTML, and the only unsafe request method natively supported by HTML was POST -- and this was catastrophically successful.
So POST is fine.
Where things tend to get tricky is when you are trying to support generic components that want to take advantage of caching. Then, you need to be thinking about the rules for invalidating cached data when you design your protocol.

Related

Rest api with generic User

I created a few Rest apis right now and I always preferred a solution, where I created an endpoint for each resource.
For example:
GET .../employees/{id}/account
GET .../supervisors/{id}/account
and the same with the other http methods like put, post and delete. This blows up my api pretty much. My rest apis in general preferred redundancy to reduce complexity but in this cases it always feels a bit cumbersome. So I create another approach where I work with inheritance to keep the "dry" principle.
In this case there is a base class User and via inheritance my employee and supervisor model extends from it. Now I only need one endpoint like
GET .../accounts/{id}
and the server decides which object is returned. Also while this thins out my api, it increases complexity and in my api documentation ( where I use spring rest docs ) I have to document two different Objects for the same endpoint.
Now I am not sure about what is the right way to do it ( or at least the better way ). When I think about Rest, I think in resources. So my employees are a seperate resource as well as my supervisors.
Because I always followed this approach, I tink I might be mentally run in it and maybe lost the objectivity.
It would be great if you can give my any objective advice on how this should be handled.
I built an online service that deals with this too. It's called Wirespec:
https://wirespec.dev
The backend automatically creates the url for users and their endpoints dynamically with very little code. The code for handling the frontend is written in Kotlin while the backend for generating APIs for users is written in Node.js. In both cases, the amount of code is very negligible and self-maintaining, meaning that if the user changes the name of their API, the endpoint automatically updates with the name. Here are some examples:
API: https://wirespec.dev/Wirespec/projects/apis/Stackoverflow/apis/getUserDetails
Endpoint: https://api.wirespec.dev/wirespec/stackoverflow/getuserdetails?id=100
So to answer your question, it really doesn't matter where you place the username in the url.
Try signing in to Wirespec with your Github account and you'll see where your Github username appears in the url.
There is, unfortunately, no wright or wrong answer to this one and it soley depends on how you want to design things.
With that being said, you need to distinguish between client and server. A client shouldn't know the nifty details of your API. It is just an arbitrary consumer of your API that is fed all the information it needs in order to make informed choices. I.e. if you want the client to send some data to the server that follows a certain structure, the best advice is to use from-like representations, such as HAL forms, Ion or even HTML. Forms not only teach a client about the respective properties a resource supports but also about the HTTP operation to use, the target URI to send the request to as well as the representation format to send the data in, which in case of HTML is application/x-www-form-urlencoded most of the time.
In regards to receiving data from the server, a client shouldn't attempt to extract knowledge from URIs directly, as they may change over time and thus break clients that rely on such a methodology, but rely on link relation names. Per URI there might be multiple link relation names attached to that URI. A client not knowing the meaning of one should simply ignore it. Here, either one of the standardized link relation names should be used or an extension mechanism as defined by Web linking. While an arbitrary client might not make sense from this "arbitrary string" out of the box, the link relation name may be considered the predicate in a tripple often used in ontologies where the link relation name "connects" the current resource with the one the link relation was annotated for. For a set of URIs and link relation names you might therefore "learn" a semantic graph over all the resources and how they are connected to each other. I.e. you might annotate an URI pointing to a form resource with prefetch to hint a client that it may load the content of the referenced URI if it is IDLE as the likelihood is high that the client will be interested to load that resource next anyway. The same URI might also be annotated with edit-form to hint a client that the resource will provide an edit form to send some data to the server. It might also contain a Web linking extension such as https://acme.org/ref/orderForm that allows clients, that support such a custom extension, to react to such a resource accordingly.
In your accounts example, it is totally fine to return different data for different resources of the same URI-path. I.e. resource A pointing to an employee account might only contain properties name, age, position, salery while resource B pointing to a supervisor could also contain a list of subordinates or the like. To a generic HTTP client these are two totally different resources even though they used a URI structure like /accounts/{id}. Resources in a REST architecture are untyped, meaning they don't have a type ouf of the box per se. Think of some arbitrary Web page you access through your browser. Your browser is not aware of whether the Web page it renders contains details about a specific car or about the most recent local news. HTML is designed to express a multitude of different data in the same way. Different media types though may provide more concrete hints about the data exchanged. I.e. text/vcard, applciation/vcard+xml or application/vcard+json all may respresent data describing an entity (i.e. human person, jusistic entity, animal, ...) while application/mathml+xml might be used to express certain mathematical formulas and so on. The more general a media type is, the more wiedspread usage it may find. With more narrow media types however you can provide more specific support. With content type negotiation you also have a tool at your hand where a client can express its capabilities to servers and if the server/API is smart enough it can respond with a representation the client is able to handle.
This in essence is all what REST is and if followed correctly allow the decoupling of clients from specific servers. While this might sound confusing and burdensome to implement at first, these techniques are intended if you strive for a long-lasting environment that still is able to operate in decateds to come. Evolution is inherently integrated into this phiolosophy and supported by the decoupled design. If you don't need all of that, REST might not be the thing you want to do actually. Buf if you still want something like REST, you for sure should design the interactions between client and server as if you'd intereact with a typical Web server. After all, REST is just a generalization of the concepts used on the Web quite successfully for the past two decades.

REST API design for non-CRUD actions, e.g. save, deploy, execute code

Resource in my REST API context is application code written in some programming language. CRUD operations that can be easily mapped to HTTP verbs are save/edit/delete code. Non-CRUD operations that are difficult to map to HTTP methods are deploy the code on server, execute the code, and undeploy.
Common suggestions I came across in SO are:
Restructure the action to appear like a field of a resource, e.g. if your action is to activate an engine, design URI: PATCH engines/123, body: {"status":"active"}
Treat the action like a sub-resource, e.g. PUT engines/123/active without a body
Use query parameters, e.g. PUT engines/123?activate=true
Be pragmatic and go for a non-RESTful, RPC-style URL, e.g. PUT engines/activate?id=123
I am definitely not able to fit deploy/undeploy/execute code actions to a resource as suggested in #1 and #2. Could you please share your opinion how best we can design the APIs for these actions?
Could you please share your opinion how best we can design the APIs for these actions?
Create/Update/Delete information resources, and as a side effect of that, do work behind the API.
So think documents.
One very good example: In RESTful Casuistry, Tim Bray asked about an api to shut down a machine. Seth Ladd's response, in particular, is important to read
Fundamentally, REST is a bureaucracy that solves problems with paperwork. If you want to get anything done, you submit the right form; which becomes an information resource describing what you want done.
PUT /deploymentRequests/abcde
Please find the artifacts from build 12345 and deploy that artifact
to machine 67890
201 Created
The request is just a document, in exactly the same way a sticky note on your desk asking you to address some task is a document.
As far as REST is concerned, the spelling of the URI absolutely does not matter; but from the point of view of a human readable naming convention, start from the fact that the resource is the document -- not the side effect that you want the document to have.
So, for example, it's totally normal and compliant with REST that the document that describes the current state of a thing and the document that describes changes you want to make to a thing are different documents with different identifiers.
I think you are looking for controllers, according to REST API design RuleBook:
A controller resource models a procedural concept.
Controller resources are like executable functions, with parameters and return values; inputs and outputs.
Like a traditional web application’s use of HTML forms, a REST API relies on controller resources to perform application-specific actions that cannot be logically mapped to one of the standard methods (create, retrieve, update, and delete, also known as CRUD).
Controller names typically appear as the last segment in a URI path, with no child resources to follow them in the hierarchy.
The example below shows a controller resource that allows a client to resend an alert to a user:
POST /alerts/245743/resend
and also:
POST should be used to create a new resource within a collection and execute controllers.
CRUD operations that can be easily mapped to HTTP verbs are
save/edit/delete code. Non-CRUD operations that are difficult to map
to HTTP methods are deploy the code on server, execute the code, and
undeploy.
I think you misunderstood the whole concept. You map operations to the HTTP method and URI, not just to the HTTP method. In the case of CRUD this is evident. In the case of "non-CRUD", you need to add a new resource with a different URI instead of trying to add a new HTTP method to the list.
PATCH is for updating a resource just like PUT, but in the case of PATCH you send update instructions instead of a representation. Sure it can be used or POST can be used too. Using PUT is not a good idea if you don't send a representation of the new resource state in the body.
So any of these can be good:
PATCH engines/123 "activate"
PUT engines/123/state "active"
POST engines/123/activation null
You can do the same with "deploy/undeploy/execute":
PATCH engines/123 "deploy"
PUT engines/123/state "before-deploy"
POST engines/123/execution null
This is just a recommendation though. You can choose the verb based on the HTTP standard and I think it is better to avoid using verbs in the URI, I use just nouns, because it makes sense this way. The URI is not that important though, it is like nice URIs on web pages, it looks good, but nobody really cares unless they have to write it down. Just to make it clear, this is still not REST unless you send these hyperlinks in your responses.
{
id: "engines/123",
type: "docs/engine",
operations: [
{
operation: "docs/engine/activation",
id: "engines/123",
method: "PATCH",
body: "activate"
}
]
}
Using RDF and ontologies takes this a lot further.

Three questions about designing REST services

I'm trying to design REST services in a correct way, but encountered a few moments I'm not sure of, but should be pretty common:
For example, I have entity car and I get it by car/{id}. What if I want to have a separate requests for car details (object with a lot of additional properties)? Should it look like car/details/{id} or car/{id}/details?
I want to call some action not from CRUD, like upload or uploadAndProcess. I can't name them directly, since verbs are not allowed in REST. How the request should look like? Something like POST car/{id}/upload/activate or POST car/{id}?upload=true,activate=true?
I've read few articles that says, that it's not allowed to use anything in path variables except ids, and everything else should be sent as request attributes. And the other says, that it's ok to use them for required attributes. Which is true?
ad 1)
From a REST viewpoint, it does not matter. URL patterns are not part of the REST principles.
ad 2)
REST is about Resources. What are the resources behind the methods you want to call? The activation of a car could be modeled as a resource.
Or do you want to manipulate an existing resource? In this case use a POST /car/{id} with the properties you want to change in the request body.
ad 3)
Both are false. REST says nothing about which part of an URL has what meaning. The important thing is that an URL identifies a resource. If the identifiying is done using the path or query parameters does not matter.
You should review Rest In Practice, by Jim Webber.
Short answer to #2: the resources that enable your application protocol are NOT entities in your domain model; they are end points that know how to receive and process documents -- the changes that happen to your domain model are a side effect of the document processing.
HTTP is a CRUD application for documents. So what you want in your RESTful app is to CRUD a document that describes the changes you want applied to your domain model. The document is your command message, the resource you send it to is either a command resource or a command collection resource
As noted by #Display Name, REST doesn't care what spelling you use for your identifiers. You can use hash values for all of your identifiers, and that's OK.
The restrictions you are referencing here actually come from various URI design guidelines. You should follow whatever guidelines are in place for your project. If writing your own, the most important thing would be to make sure that you are consistent with the RFC 3986. Which basically says that hierarchical information belongs in the path, and non hierarchical information doesn't.
You may have missed this older discussion: REST API Best practices: Where to put parameters?

Are these valid disadvantages of a REST-ful API?

I get the basic idea of REST-ful API, but I can see how they're not ideal. I want to know where I'm wrong on the following assumptions.
REST-ful API unnecessarily exposes models
On a REST-ful API, it's usually a set of actions e.g CRUD on an entity. Sometimes performing a business action requires many models to be manipulated, and not just one.
For example, consider a business action of refunding an order, which then decreases a buyer's rating. Several possible models are involved here e.g Order, OrderItem, Payment, Buyer, Refund.
We often end up exposing single 'parent' model with an action that updates itself and its sub-models, or we end up exposing many models that must be updated appropriately to successfully accomplish the business action as a whole.
REST-ful API forces one to think in terms of manipulating models instead of the natural behavior of stating intent
Consider a customer service rating application. A customer can state his / her happiness once a support call ends e.g "I'm satisfied" / "I'm angry" / "I'm neutral".
In a REST-ful API, the customer has to figure out what exact model to manipulate in order to state how he feels. Perhaps a CustomerResponse model, or a Feedback model. Why can't the customer just hit an endpoint, identify himself and simply state whether he's happy or not, without having to know the underlying model that tracks his response?
REST-ful API Update action oversimplifies too much
Sometimes on a model, you want to do more than just an update. An update can be many things.
Consider a Word model. You can reverse the characters, randomize the characters, uppercase / lowercase the characters, split the word and many other actions that actually means a Word model is 'updated' in a certain way.
At this point, exposing just an Update action on Word probably oversimplifies how rich the Word model can be.
I do not believe the points you state above are really drawbacks of a RESTful API. More analytically:
REST-ful API unnecessarily exposes models
No models are exposed. Everything is handled by a single controller. The only thing that is exposed to the user is the route of the appropriate controller.
REST-ful API forces one to think in terms of manipulating models instead of the natural behavior of stating intent
Same as above. A single controller can handle the different customer happiness states. The distinction can be made by passing different post paramenters (ex. { state: "happy"}).
REST-ful API Update action oversimplifies too much
Nothing stops you from manipulating the data that needs to be sent to your model before updating it. You can do whatever you want, however complex it may be, before updating your model.
Finally, I believe that a RESTful API is only as good as its implementation. Furthermore, I believe that if you wanted to find a flaw to the REST technique is the fact that you cannot initiate transactions or push notifications server-side
First, Web service APIs that adhere to the REST architectural constraints are called RESTful APIs. HTTP based RESTful APIs are defined with these aspects:
base URI, such as http://example.com/resources/
an Internet media type for the data. This is often JSON but can be any other valid Internet media type (e.g. XML, Atom, microformats, images, etc.)
standard HTTP methods (e.g., GET, PUT, POST, or DELETE)
hypertext links to reference state
hypertext links to reference related resources
Now with your questions:
REST-ful API unnecessarily exposes models
In your example, if you want to refund someone, you obviously use more than one model.
RESTful doesn't means that you expose only one model, for example, a POST on a /api/refunds is a RESTful way of doing it without expose a single model.
The only thing peole see from you API are routes to your different actions in your different controllers
REST-ful API forces one to think in terms of manipulating models instead of the natural behavior of stating intent
Your RESTful API is called from a front-end (smartphone app, javascript app, etc..) or a back-end (a server), the end user (here, the satisfied/angry/neutral client) is not obligated to see the url called by your front-end, the satisfaction form could be here /support/survey and the server API url could be a POST to /api/support_calls/1/surveys.
REST-ful API Update action oversimplifies too much
An PUT on a RESTful route does NOT means that you should only update one model. You can manipulate params, create a model, update another, and then, update your main model.
Finally
Dont forget that RESTful architecture is a ROUTE and URL architecture created for developpers, you can do anything you want in your controllers, this is just a convention-based way of exposing your URLs to API's consumers
I'll try to address your concerns, but keep in mind that the topic is very mch debatable, so take this as my humble opinion..
1) about the model being unnecessary exposed, well I think it is mostly a matter of modeling your domain entities in a way that allows you to express all the available action and concepts in terms of 'doing something on a resource'. In the refund example, you could for instance model a Refund entity and perform actions on that.
2) here too is a matter of modeling domain entities and services. Your happiness service could be a matter of having a service accepting a user id and an integer expressing the user's satissfaction level.
3) In the case of the Word model, you can simply use the PATCH (or PUT) http verb and provide a service that simply overwrites the resource, which would in turn be manipulated by the client.
Again, REST is a paradigm, so it is (among other things) a way to organize the objects of your domain and the actions that can be performed on those objects. Obviously it has drawbacks and limitations, but I personally think that it is quite 'transparent' (i.e. not imposing artificial constraints on your programming), and that it is quite easy to use, being mostly based on widely accepted conventions and technologies (i.e. http verbs and so on).

Designing RESTful URLs for web pages

Most REST tutorials arranged resources as following:
GET /car/ -> list of cars
GET /car/<id>/ -> info about specific car
POST /car/ -> create a new car
but when building web applications for use in browsers, there is a missing link that are rarely discussed, before you can POST to /car/, you need to GET a form for creating a new resource (car). What should the URL for this form be?
I typically used:
GET /car/new/ -> form for creating a new car
POST /car/new/ -> redirect to /car/<id>/ if item is created else show form with invalid fields highlighted
but according to http://www.slideshare.net/Wombert/phpjp-urls-rest this is not a good REST URL. I can see why it's not a good REST, because "new" is really used as a verb and not a resource, but where should the form be then, because GET /car/ is already used for listing cars, so you can't use GET /car/ for the form for new cars.
In short, my question is: "What is the RESTful URL for 'create resource form'?"
On a slightly related note, even in a web service, it is sometimes not always wise to rely on the client knowing the schema in advance, therefore even in web services there could be a need to be a way for client to request the resource's current schema. AFAICS, this as a similar situation with the need to GET a create form (i.e. the form is sort of like a schema which describes how to construct POST query for creating the resource). Is my line of thought here correct?
REST does not care too much about what your URI looks like as long as it identifies one unique resource and is self-describing. Meet those criteria, and beyond that, it is personal preference. Nothing prohibits using a verb in a URI if it makes sense to use one.
In regards to your slightly related note, what you hint at with the form being a schema is media type. RESTful architecture concerns the client and the server both understanding the media types used to represent the application state.
A REST API should spend almost all of its descriptive effort in
defining the media type(s) used for representing resources and driving
application state, or in defining extended relation names and/or
hypertext-enabled mark-up for existing standard media types. Any
effort spent describing what methods to use on what URIs of interest
should be entirely defined within the scope of the processing rules
for a media type (and, in most cases, already defined by existing
media types).
Read more here: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
That is from Roy Fielding, the man who defined REST. In general, your media types should be extensible -- that is, any changes should add on and not break older clients unless necessary.
I always assumed that "form" as such is not a resource, so /<name>/new is okay - forms are not usual elements of APIs. Author of the slides put that on a "bad" list, but didn't provide a correct one - I assume he was so RESTful that he forgot to think about such cases.