RESTful API - Ignore invalid PUT request? - api

I build a simple API for a bookmark manager, where the URL of record should only be stored once. Record 001 with www.example.com already exists beside record 002 with www.stuff.com.
If I update record 002 with the url www.example.com, should I ignore the complete request and send back an error message or is it better to update all valid parts and just send an errror message, that says, that the url/bookmark already exists?

With a PUT, the expectation is that the entire operation will succeed or fail:
The PUT method requests that the state of the target resource be
created or replaced with the state defined by the representation
enclosed in the request message payload. A successful PUT of a given
representation would suggest that a subsequent GET on that same
target resource will result in an equivalent representation being
sent in a 200 (OK) response.
https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4
You should send an error for an invalid PUT (since the URL already exists and cannot be in two records at the same time) and not apply any of the other updates.
For partial updates you might consider a PATCH, but in this case I don't think you would go this direction since:
If the entire patch document
cannot be successfully applied, then the server MUST NOT apply any of
the changes.
https://www.rfc-editor.org/rfc/rfc5789

Related

Http status code when data not found in Database

I'm trying to understand which Http Status Code to use in the following use case
The user tries to do a GET on an endpoint with an input ID.
The requested data is not available in the database.
Should the service send back:
404 - Not Found
As the data is NOT FOUND in the database
400 - Bad Request
As the data in the input request is not valid or present in the db
200 - OK with null response
200 - OK with an error message
In this case we can use a standard error message, with a contract that spans across all the 200 OK responses (like below).
BaseResponse {
Errors [{
Message: "Data Not Found"
}],
Response: null
}
Which is the right (or standard) approach to follow?
Thanks in advance.
Which is the right (or standard) approach to follow?
If you are following the REST API Architecture, you should follow these guidelines:
400 The request could not be understood by the server due to incorrect syntax. The client SHOULD NOT repeat the request without modifications.
It means that you received a bad request data, like an ID in alphanumeric format when you want only numeric IDs. Typically it refers to bad input formats or security checks (like an input array with a maxLength)
404 The server can not find the requested resource.
The ID format is valid and you can't find the resource in the data source.
If you don't follow any standard architecture, you should define how you want to manage these cases and share your thought with the team and customers.
In many legacy applications, an HTTP status 200 with errors field is very common since very-old clients were not so good to manage errors.

HTTP status code response when there is not matched data with DB

I am building an API about email auth code.
Its process is simple.
input random code (client browser)
request with input code. (client browser)
receive the request (server)
scan the code from DB (server)
there is no code matched (server)
return a response with status code.
There are many status code, (2xx, 4xx, 5xx);
but I don't know which status code number is the most proper for this case.
It depends on the semantics you want to give your request. E.g.:
The API should search for items matching the query and return a list of results, like GET /codes?q=4ba69g. Think a "search page". In this case, an empty result [] is a perfectly valid result; nothing was wrong with the query, it just didn't return any matches. That's a 200 OK, or maybe a 204 No Content if you want to omit the empty response body entirely.
The code is treated like a resource, e.g. GET /codes/4ba69g. In this case a missing code would result in a 404 Not Found.
It's an action you want to perform which may fail, e.g. POST /login. If the user supplied the wrong credentials/code and hence the action cannot complete, that's a client-side error and therefore a 400 Bad Request.

Failed to respond to incoming message using data source row correlation

I am totally new to Parasoft virtualize. I created a virtual asset and added three fields in my data source correlation, My request xml has 4 fields. I am getting this error after processing the request.
<Reason>Failed to respond to incoming message using data source row correlation</Reason>
<Details>Values in incoming message did not match values in the data source "GetSubscriptionOperationsRequest"</Details>
Any suggestions on what might be the problem here?
The message which you are getting explains your problem.
The virtual asset cannot correlate your request with data in your data source to build response.
Try to send request with one of the values from column used for Datasource's corelation in your responder.
That value should be in request's filed used by correlation.
Maybe you should try to add catch all responder to see if you have correct corelation between incoming requests and your responder.
You can also ask Parasoft's technical support for help.

Can PUT request change the URL?

My application with a HTTP API provides some resources that are identified by name. So, the URLs are constructed as the following:
/path/to/resources/<name>
For example:
/path/to/resources/my_resource
The resources can be updated with PUT operations. It is also allowed to rename a resource with such an update.
PUT /path/to/resources/my_resource
{"name": "new_name", <other properties>}
Response:
HTTP/1.1 204 No content
As a result, the updated resource is now accessible under a new URL:
GET /path/to/resources/new_name
Response:
HTTP/1.1 200 OK
{"name": "new_name", <other properties>}
The old URL is no longer valid:
GET /path/to/resources/my_resource
Response:
HTTP/1.1 404 Not found
Is such behavior correct? Should the PUT operation return the Location header with a new URL? Is it OK to return the Location header with the 204 No content status?
After writing this question I found another, quite similar: REST API Design : Is it ok to change the resource identifier during a PUT call?
The accepted answer was that it is allowed, but not recommended. Still don't know what about the Location header, though.
By changing a resource identifier, I understand you are deleting a resource and creating a new one. So, the approach you described in the question is basically a delete operation using the wrong HTTP verb.
According to the RFC 7231, the current reference for HTTP/1.1, PUT requests are used to create or replace a resource:
4.3.4. PUT
The PUT method requests that the state of the target resource be
created or replaced with the state defined by the representation
enclosed in the request message payload.
[...]
If the target resource does not have a current representation and the
PUT successfully creates one, then the origin server MUST inform the
user agent by sending a 201 (Created) response. If the target
resource does have a current representation and that representation
is successfully modified in accordance with the state of the enclosed
representation, then the origin server MUST send either a 200 (OK) or
a 204 (No Content) response to indicate successful completion of the
request.
[...]
I would do the following when the resource identifier needs to be changed:
Perform a DELETE in the existing resource. The response would be a 204 indicating the request was fulfilled.
Perform a POST or PUT to create the resource using the new identifier. The response would be a 201 indicating the resource was created. The response would contain a Location header indicating where the resource is located.
To replace the state of the target resource (keeping the resource identifier), perform a PUT and return a 204 to indicate the operation succeeded.
I don't know about your requirements, but I wouldn't allow the user to change or create the identifier of a resource. I would assume the resource identifier is immutable and should be generated by the application (UUID, of example) or an identifier generated by the database.
I agree with Cássio Mazzochi Molin's answer. However the question is theoretical one, whether renaming the resource really changes the 'identity' of a resource.
For example if a person's name changes, that does not change who the person is. I still would like the URI I previously got for the "same" person to work, even after the name change.
So I guess my point is not to include non-identity related information into the URI. Include an Id number or similar content-unrelated information.
Don't do a DELETE and PUT to another URI (don't relocate the resource) if the identity of the object did not change.

What is the correct value or status code to indicate that a username record could not be updated?

I'm implementing a basic service to add usernames to user records in a database. The service first checks if the username exists and if it does returns some value to tell the client that the username is already taken. If the username is available it updates the user record and returns "OK". In this application the client is a native IOS mobile app and the server is node.js. But that shouldn't be relevant to this question.
For this service, what would you recommend I use as my return values? For example, when successful should I return a status code 200? A boolean value? A custom string? Similarly for the unsuccessful condition what would the recommended and customary return value be?
The status 201 is intented to be used when some resource is created. So when your user is created you should set status code 201 and set it to 200 when the same request does an update. Additionally you can return the ID id the created/updated user. IMHO you should keep create and update as separate services.
You can use apporpriate 4xx errors (Refer link) when errors happen. Always keep a status message attribute in your response if your response is XML or JSON. You can set appropriate messages into this and the mobile app can check this message based on the HTTP Status Code you give.
I would return a 201 for the successful condition and a 400 or 409 for the unsuccessful condition.
Hope that helps!
Brandon