Putting the HTTP specification aside, what is the main reason or advantage of appending the id of a resource in HTTP PUT? - asp.net

If I can do the following when creating a record,
URI: /api/roles/
Method: POST
Content: { Id: 0, Name: 'Admin', Description: 'Administration Role' }
Can I just do this if I want to update a record?
URI: /api/roles/
Method: PUT
Content: { Id: 1001, Name: 'Admin', Description: 'Administration Role' }
...because I can just get the identifier in the Id field.
Instead of doing this?
URI: /api/roles/1001
Method: PUT
Content: { Id: 1001, Name: 'Admin', Description: 'Administration Role' }
...specifying the Id value twice. By the way, I cannot remove the Id field in the content.
If not, why? What is the main reason or advantage of appending the id of a resource in HTTP PUT, putting the HTTP specification aside?

Adding ID resource denotes one of the steps of RESTful API
You could look for further discussion here : What is the advantage of using REST instead of non-REST HTTP?
RESTful design principles specify HATEOAS which roughly states that interaction with an endpoint should be defined within metadata that comes with the output representation and not based on out-of-band information.
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

I agree there seems to be a strange redundancy in specifying the ID in the URL as well as the request body.
As I see it, the reason is not technical, but 'cultural'.
Whenever the URL is /api/roles/ you indicate that the list is being manipulated, whereas /api/roles/{id} clearly points to the target being a list item.

Related

JSON API Standard

I have a doubt what is a better option when using json api standard and communication between backend and frontend. I need only one attribute from author association - „username” and other stuff should be hidden for user that fetch this
Case a)
data: [
{
id: „100”,
type: „resource1”,
attributes: {…},
relationships: {author: {data: {id: „10”, type: „author”}}}
}
],
included: [
{
id: „10”,
type: „author”,
attributes: {username: „name”},
relationships: {resources1: {data: [{id: „100”, type: „resource1”}]}}
}
]
Case b)
data: [
{
id: „100”,
type: „resource1”,
attributes: {authorName: „name”, …},
relationships: {author: {data: {id: „10”, type: „author”}}}
}
],
included: []
Case a) looks semantic but there serve much more information in payload
Case b) is faster to get what I want from author (one attribute „username” and this is added in additional attribute: „authorName”), so also don’t need to pleas with associations in frontend side.
Any thoughts which is better practice and why?
Strictly speaking both case a and case b are valid per JSON:API specification.
In case a username is an attribute of author resource. In case b authorName is an attribute of resource1. author resource may have a username attribute in case b as well. In that case you have duplicated state.
I would recommend to only use duplicated state if you have very good reasons. Duplicated state increases complexity - both on server- as well as client-side. Keeping both attributes in sync comes with high costs. E.g. you need to update a client that resource1 changed after a successful update request, which affected the username of author resource. And the client need to parse that response and update the local cache.
There are some reasons, in which duplicating state pays off for good reasons. Calculated values, which would require a client to fetch many resources to calculate them, is a typical example. E.g. you may decide to introduce a averageRating attribute on a product resource because without a client would need to fetch all related ratings of a product only to calculate it.
Trying to reduce payload size is nearly never a good reason to accept the increased complexity. If you consider compressing and package sizes at network level, the raw payload size often doesn't make a big difference.

Firebase POST to Realtime Database adding an extra section

I'm trying to upload data into Firebase Realtime Database I have tried first doing a POST through the API this is my Query:
Method: POST
EndPoint: https://[PROJECT_ID].firebaseio.com/users/5Vzshkdlu8W3sDSZMt9bc9SyhiF8.json
Note I'm using my Project ID
Headers: 'Content-Type': 'application/json'
Body:
{
"name": "Rene Alas",
"correo": "[Email]",
"image": "[URL to my Image]",
"title": "Albo Aficionado",
"acceso": 0
}
I tried this on Postman but it gets me an additional part:
As you can see it added a middle part between my given ID and the Data which is Auto Assigned in this particular example:
MTLim4FiFfdeZP4yPZP
Any Ideas how I can put the information underneath the given ID so it doesn't auto assign that key?
Kind Regards?
HTTP semantics say that POST creates a new resource under the location, which is what Firebase does in your situation.
If you want to write a value you specify to the location and overwrite any existing data there, that'd be a call with the PUT method.
If you want the data you pass (on a key by key basis) to be combined with data already at the location, use the PATCH method that Martin mentions.
If you want to update that node, the HTTP request method is PATCH and not POST.
This can be used to update individual childs, see the examples.

Use PUT or PATCH verb when request is updating and deleting: Real life design

I've been trying to get the HTTP verbs right lately, however I have a doubt regarding using PUT, PATCH or even POST for the following scenario.
The front end part is sending the following JSON data:
{
name: "Spanish-01",
code: "ESP01",
students: [{
IdStudent: 1,
name: "Peter Parker"
},
{
IdStudent: 2
name: "Ben Reilly",
dirtyRemove: true
}]
}
The back end code will update the Class record (e.g name and code). However, it will also delete the students with flag dirtyRemove, and those live in another table called Student.
So what's the rule here? Since PUT and PATCH according to w3.org here is for updating an existing resource. In this case the back end is both updating and deleting at the same time?
Should I use PUT or PATCH or neither?
NOTE: Don't mind about the FE part, I minimized the scope in order to get a more straightforward example
How your resources are implemented internally using tables is an implementation detail. It doesn't matter.
That said, your example payload doesn't fit PUT (to remove a student, you would omit it). It might fit PATCH, if you properly label the payload with a content type describing what semantics you expect.
Nit: the HTTP spec is not a W3 document, and the version you're looking at is outdated.

Rest API - Friends collection creation

Users can basically add other user(s) as a friend. So, I am not creating another user resource but linking two resources.
Questions
What is the best strategy to handle this?
What is the appropriate Verb for this case?
I heard there is a LINK verb, which seems to be appropriate.
And also I read, I can use PATCH verb to apply patch on resource(s).
If so, can I do like this
PATCH /users/{id}/friends
You might consider creating a new object.
If you separated out a friendship object, you would be able to create and modify them without updating the User(s). Each friendship would have two user keys. It would also be a great place to hang extra information about the friendship, such as 'friends since' value.
POST /friendships
{
primaryUser: 43,
secondaryUser: 3
since: "03/16/2010"
}
201 CREATED
location: /friendships/635
Then a query to user 43 could be written to include an array of either user ids, friendship ids, or embedded objects.
GET /users/43
200 SUCCESS
{
id: 43,
name: "john",
friends: [3]
}
Or
200 SUCCESS
{
id: 43,
name: "john",
friends: [635]
}
or
200 SUCCESS
{
id: 43,
name: "john",
friends: [
{
id: 635,
primaryUser: 43,
secondaryUser: 3,
since: "03/16/2010"
}
]
}
Semantics for updating/removing are much more straight forward. 'Removing' a friendship looks better as a DELETE rather than a PATCH or PUT imo.
"Linking a resource" really just means "update one resource to include a link to another".
That means that you should issue a PUT or POST to resource A with a new representation that includes the new reference to resource B.
If it's a bi-directional relationship then by virtue of making that PUT/POST on resource A you should also see the reference to A included the next time you GET resource B, too.

restful-like CRUD operation url pattern for nested model

Generally,the CRUD operation url pattern for model can be like this(Suppose the Model is Post):
new: /posts/new(get)
create:/posts/(post)
edit:/posts/edit(get)
update:/posts/1(put)
get:/posts/1(get)
However if there is a nested model "Comment".
And the association of the "Post" and "Comment" is one-many.
So what should the CURD operation url pattern like for comments ?
new: /posts/1/comments/new or /comments/new
create:?
edit:?
update:?
.......
What is the best practice?
Update:
It seems that the url for comment should be like this:
Get one comment for one post: /posts/1/comments/1
create: /posts/1/comments
update: /posts/1/comments/1
delete: /posts/1/comments/1
Now I am confused with the update and delete operation.
For update and delete: /posts/1/comments/1
SInce the comment id is specified,so I wonder if the /posts/1 inside the url is necessary?
I think the key is whether a comment is "contained" by the post resource. Remember that RESTful urls should be permalinks so under all of your scenarios, the end point to a specific comment(s) must not change. It sounds like it's containted so the url pattern can have the comment nested within the post. If that's not the case (e.g. a comment could move to another post which if nested would change the url) then you want a more flat structure with /comment/{id} urls referenced by the post resource).
The key is if it's a RESTful "Hypermedia API" then like the web it constantly links to the nested or referenced resources. It doesn't rely on the client necessarily understanding the REST pattern or special knowledge as to what end point holds the referenced or contained
resource.
http://blog.steveklabnik.com/posts/2012-02-23-rest-is-over
If a 'comment' is the resource(s) under a 'post' resource:
([httpVerb] /url)
get a post:
[get] /posts/{id}
body has a couple options - either it contains the full deep comments array
(depends on how much data, chat pattern)
{
id:xxx,
title:my post,
comments: [...]
}
... or it just contains the post resource with a url reference to the comments e.g.
{
id: xxx,
title: my post,
commentsUrl: /posts/xxx/comments
}
could also have an option like this (or other options to control depth):
[get] /posts/{id}?deep=true
get a collection of comments within a post:
[get] /posts/{id}/comments
returns 200 and an array of comments in the response body
create a comment for a post:
[post] /posts/{id}/comments
body contains json object to create
returns a 201 created
edit a comment under post:
[patch|post] /posts/{id}/comments/{id}
body contains json object with subset of fields/data to update
returns a 200
replace a post:
[put] /posts/{id}/comment/{id}
body contains json object to *replace*
returns a 200
If you have tons of comments per post, you could also consider a paging pattern:
{
id: xxx,
title: myPost,
pages:6,
commentsUrl:/posts/xxx/comments/page/1
}
then:
/posts/{id}/comments/pages/{pageNo}
{
nextPage: /posts/xxx/comments/2,
pages:7,
comments:
[ { ...,...,}]
}
each page would reference the next page, the page count and an array of comments for that page. If you went with a paging pattern then each comment in the array would have a reference url to the individual comment.
If you find yourself putting an action in the url, you're probably doing something wrong. Good read: http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http
You want to use the canonical URL for delete/update, which would be the complete one. More importantly, you shouldn't be exposing your Primary Key values which come from the Database as ids in the public api that is your restful URL space. These values could change in the future based on a database update, restore from backup, or anything else, depending on vendor. And you don't want an infrastructure change making all your URLs invalid if you can help it.
If you're using /posts/{postnum}/comments/{commentnum}, you can number the public comment ids starting from 1 for every post, making for shorter, nicer URLs.

Resources