This is my WCF service, where user can find message for him.
Simple:
[OperationContract]
[WebGet(UriTemplate = "/GetMessages/{UserGLKNumber}/{UserPassword}/{SessionToken}")]
Messages GetMessages(string SessionToken, string UserPassword, string UserGLKNumber);
I have concerns about that line: {UserGLKNumber}/{UserPassword}/{SessionToken}
I have to authenticate user, before he get that messages. But with GET method, I cannot send objects, like in POST.
Is it consistent with REST pattern?
Please, clear up my doubts.
There are already posts & question about this, I am summarizing all of them
POST verb is used when are you creating a new resource (a file in your case) and repeated operations would create multiple resources on the server. This verb would make sense if uploading a file with the same name multiple times creates multiple files on the server.
PUT verb is used when you are updating an existing resource or creating a new resource with a predefined id. Multiple operations would recreate or update the same resource on the server. This verb would make sense if uploading a file with the same name for the second, third... time would overwrite the previously uploaded file.
POST everytime you are modifying some state on the server like database update, delete. GET for readonly fetching like database select.
GET: Get a collection of entries (as a feed document) or a single entry (as an entry document).
POST: Create a new entry from an entry document.
PUT: Update an existing entry with an entry document.
DELETE: Remove an entry.
Source:Difference between PUT and POST using WCF REST
Another Useful reads are:
What's the difference between a POST and a PUT HTTP REQUEST?
http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide
http://msdn.microsoft.com/en-us/magazine/dd315413.aspx
http://social.msdn.microsoft.com/Forums/vstudio/en-US/643e0d8b-80bb-45eb-8a84-318ac8de4497/difference-between-the-rest-verbs-put-and-post?forum=wcf
In terms of Restful services...
Post :
1. Its a secure to use in application rather than get.
2. Its not configure proxy server.
3. Big length of data restricted by web server.
4. Its not cached on browser.
5. Its take input as xml
Get :
1. Its a not secure to use in application rather than get.
2. Its configure proxy server.
3. Its use url encoding technique.
4. Its cached on browser.
5. Its a default if you are not declaring anyone.
6 Its take input as a string an returned a formatted output.
Related
So i have one single http post API called UpsertPerson, where it does two things:
check if Person existed in DB, if it does, update the person , then return Http code 200
if not existed in DB, create the Person, then return http 201.
So is it a good practices by having the same api return different statusCode (200,201) based on different actions(update, create)?
This is what my company does currently , i just feel like its weird. i think we should have two individual api to handle the update and create.
ninja edit my answer doesn't make as much sense because I misread the question, I thought OP used PUT not POST.
Original answer
Yes, this is an excellent practice, The best method for creating new resources is PUT, because it's idempotent and has a very specific meaning (create/replace the resource at the target URI).
The reason many people use POST for creation is for 1 specific reason: In many cases the client cannot determine the target URI of the new resource. The standard example for this is if there's auto-incrementing database ids in the URL. PUT just doesn't really work for that.
So PUT should probably be your default for creation, and POST if the client doesn't control the namespace. In practice most APIs fall in the second category.
And returning 201/200/204 depending on if a resource was created or updated is also an excellent idea.
Revision
I think having a way to 'upsert' an item without knowing the URI can be a useful optimization. I think the general design I use for building APIs is that the standard plumbing should be in place (CRUD, 1 resource per item).
But if the situation demands optimizations, I typically layer those on top of these standards. I wouldn't avoid optimizations, but adopt them on an as-needed basis. It's still nice to know if every resource has a URI, and I have a URI I can just call PUT on it.
But a POST request that either creates or updates something that already exists based on its own body should:
Return 201 Created and a Location header if something new was created.
I would probably return 200 OK + The full resource body of what was updated + a Content-Location header of the existing resource if something was updated.
Alternatively this post endpoint could also return 303 See Other and a Location header pointing to the updated resource.
Alternatively I also like at the very least sending a Link: </updated-resource>; rel="invalidates" header to give a hint to the client that if they had a cache of the resource, that cache is now invalid.
So is it a good practices by having the same api return different statusCode (200,201) based on different actions(update, create)?
Yes, if... the key thing to keep in mind is that HTTP status codes are metadata of the transfer-of-documents-over-a-network domain. So it is appropriate to return a 201 when the result of processing a POST request include the creation of new resources on the web server, because that's what the current HTTP standard says that you should do (see RFC 9110).
i think we should have two individual api to handle the update and create.
"It depends". HTTP really wants you to send request that change documents to the documents that are changed (see RFC 9111). A way to think about it is that your HTTP request handlers are really just a facade that is supposed to make your service look like a general purpose document store (aka a web site).
Using the same resource identifier whether saving a new document or saving a revised document is a pretty normal thing to do.
It's absolutely what you would want to be doing with PUT semantics and an anemic document store.
POST can be a little bit weird, because the target URI for the request is not necessarily the same as the URI for the document that will be created (ie, in resource models where the server, rather than the client, is responsible for choosing the resource identifier). A common example would be to store new documents by sending a request to a collection resource, that updates itself and selects an identifier for the new item resource that you are creating.
(Note: sending requests that update an item to the collection is a weird choice.)
I am trying build an api which conforms to the json:api spec.
My api has three resources /task, /item and /result. A task has the fields name, description and state. A item has the fields itemName. A count is kept server-site for the item and the count is returned when a user retrieves the item with a GET request. The count is incremented server-side when the item is updated. There is a one-to-many relationship between task and item. In a sense an item is appended to a task. When the tasks state changes a script runs server-side to do some processing on the associated items. Once the script finishes the output is available in the result resource.
Per the spec, I am using the POST verb to create a task and the PATCH to update a task. I just want one endpoint which handles both the create /update (appending) of an item. But, I'm not sure which verb to use? Can I use PATCH to update the item but also create an item if it doesn't exist?
I also thought that perhaps I should be using the PUT verb. But, my understanding here is that this verb is used to simply replace a resource rather than update it. I don't think this is right for my user-case as an items count is incremented when updated, so replacing it is not what I want todo. But, the count is handled server-side so a user doesn't have the option of "replacing" the count anyway.
my understanding here is that this verb is used to simply replace a resource rather than update it.
This is a common understanding - wrong, but common.
The IANA registry documents the authoritative reference for the semantics of http methods. Most of the common ones are defined by RFC 7231; PATCH is defined by RFC 5789.
PUT is an appropriate choice when the message body is a complete representation of what you want the resource to be. It may be easier to think about "saving a file"; PUT describes what the client expects the document to look like when it has been saved.
It's appropriate to use PUT for either updating a document or creating one, provided that the client knows the identifier for the document (just in the same way that we can use save to create a file, or replace a file, but we need to know the file name).
If you read the text of the specification, you'll see that - while the semantics of the request are to save the new representation "as-is", the server isn't required to do that -- the server, after all, is in control of its own documents -- so there is room to cover read only fields, or fields that should be updated by the server only. You need to have a little bit of care with the response headers to avoid implying that you saved the representation as is, but other than that you should be fine.
One of the reasons, and probably the main one, to use UUID is to avoid having a "centralized" point responsible for creating and assigning ids to resources.
That means that, for REST APIs, the clients could (and should) be able to generate, and give the UUID for a certain resource when they POST that specific resource for the first time. That would minimize problems related with successfully posting a resource for the first time but not getting the ID back as response (connectivity problems for example). That can result in a new post for some of the clients, generating duplicated resources.
My question are:
Having UUID generated by clients and being exposed in the REST API is a best practice?
Are there any other alternatives to that?
REST does not really care if the UUID is generated by the server or by the client. It just needs a unique resource-identifier in form of an URI.
What form the URI has, is not important to clients and servers - only that they are unique and may be obtained by clients (HATEOAS). You need of course also a resource on the server side which is able to create the sub-resource for you and understands that you want to provide the UUID instead of generating an own one. Instead of a UUID you could f.e. also use a url-encoded title of a blog-post or like this question a combination of hash-value and question-title 31584303/rest-api-and-uuid to uniquely identify a resource.
Generating a UUID by a client is in my opinion not used that ofen in practice, but I may be wrong on this matter. The actual question is rather, why should a client really provide an own UUID instead of letting the server create one? The client is, IMO, only interested in getting the data to the server and having some way to retrieve it at some later point, which will be provided through the location header returned in the response of a POST request.
If connection issues are an actual concern, you could let the client send an empty POST to create a resource and send back the location within the header. The content is than added via a PUT request.
There still can be some connection issues involved:
request does not reach the server
response does not reach the client
While the primer one is no issue for the client as well as for the server as no operation is executed and the request can simply be resent, the latter one will actually create a resource at the server side, though the link never reaches the client. Therefore the actual resource is in an unreferencable state unless you provide a way to iterate over all resources, which contains also the empty ones.
A server can have a cleanup thread in the back which removes empty resources after a given amount of time. If a client sends a further empty POST request but this time also receives the URI of the created resource, he can update the state of the resource via PUT. PUT is idempotent. If the server did not receive the request, the client can simply resent it. PUT has the semantic of updating existing or creating a new resource if it is not yet available. So, the server can create the resource in that case with the provided content. If the request did reach the server, a further update does not change the state of the resource.
one advantage of client-generated UUID is: the client knows the resource key even before creating the resource. no need to read the response of the POST/PUT except for errors
Synchronizing data once user gets online involves both Insert and Update (Upsert) and I'm sending both kinds of records in a single request (array) and then server iterates through records to determine insert or update.
My question is whether to use POST or PUT?
Also how a response from the server (JSON) should like in it's body? the data sent is an array, for example
{
"ids" : "15,16,17",
"success" : true
}
Edit:
And what should be the response code, it has both create and update operations:
200 OK
201 Created
REST is not CRUD. Mapping HTTP methods to CRUD operations is a convention introduced by some frameworks, but it has nothing to do with REST. Read this answer for some clarification on that.
A PUT is a complete replacement that ignores the current state of the resource. Think of the mv command in a shell. If there's nothing on the destination, it creates it. If there's something, it replaces completely, ignoring whatever is in there. That's how a PUT should work. Ideally, your application should have an uniform implementation of PUT that works in the exact same way with any URI that supports the method..
A POST submits the payload to be processed by the target resource under predefined rules. This means you can use POST for any operation that isn't already standardized by the HTTP protocol.
In your case, it's clearly not a complete replacement, so it's not a case for PUT. Use POST.
I am new to Restful concept and have to design a simple API for a media analysis service I need to set up, to perform various tasks, e.g. face analysis, region detection, etc. on uploaded images and video.
Outline of my initial design is as follows:
Client POSTs a configuration XML file to http://manalysis.com/facerecognition. This creates a profile that can be used for multiple analysis sessions. Response XML includes a ProfileID to refer to this profile. Clients can skip this step to use the default config parameters
Client POSTs video data to be analyzed to http://manalysis.com/facerecognition (with ProfileID as a parameter, if it's set up). This creates an analysis session. Return XML has the SessionID.
Client can send a GET to http://manalysis.com/facerecognition/SessionID to receive the status of the session.
Am I on the right track? Specifically, I have the following questions:
Should I include facerecognition in the URL? Roy Fielding says that "a REST API must not define fixed resource names or hierarchies" Is this an instance of that mistake?
The analysis results can either be returned to the client in one large XML file or when each event is detected. How should I tell the analysis engine where to return the results?
Should I explicitly delete a profile when analysis is done, through a DELETE call?
Thanks,
C
You can fix the entry point url,
GET /facerecognition
<FaceRecognitionService>
<Profiles href="/facerecognition/profiles"/>
<AnalysisRequests href="/facerecognition/analysisrequests"/>
</FaceRecognitionService>
Create a new profile by posting the XML profile to the URL in the href attribute of the Profiles element
POST /facerecognition/profiles
201 - Created
Location: /facerecognition/profile/33
Initiate the analysis by creating a new Analysis Request. I would avoid using the term session as it is too generic and has lots of negative associations in the REST world.
POST /facerecognition/analysisrequests?profileId=33
201 - Created
Location: /facerecognition/analysisrequest/2103
Check the status of the process
GET /facerecognition/analysisrequest/2103
<AnalysisRequest>
<Status>Processing</Status>
<Cancel Method="DELETE" href="/facerecognition/analysisrequest/2103" />
</AnalysisRequest>
when the processing has finished, the same GET could return
<AnalysisRequest>
<Status>Completed</Status>
<Results href="/facerecognition/analysisrequest/2103/results" />
</AnalysisRequest>
The specific URLs that I have chosen are relatively arbitrary, you can use whatever is the clearest to you.