Custom Response code and response message in restfull and SOAP services - api

I'm developing Web services restful and SOAP Services, I'm wondering what if I use custom response code and custom response message included in response body and the http response status code in most cases will be returned as (200 ok) so it will be easier to handle errors, I'm wondering if that way is acceptable

In HTTP, the definition of a status-line is found in RFC 7230
status-line = HTTP-version SP status-code SP reason-phrase CRLF
reason-phrase turns out to not be particularly important; clients are expected to ignore the reason phrase when processing an HTTP response.
The rest of the response message is to be interpreted in light of the semantics defined for that status code
The status code is an important piece of metadata in the transfer of documents over a network domain; general purpose clients use it to understand the nature of the HTTP response so that they can do intelligent things.
(Among the intelligent things: automatically following redirects, retrying requests with authentication credentials attached, cache invalidation).
There's a lot of code out on the internet that you don't control, that understands standardized HTTP semantics. When you fail to respect the standardized semantics, you introduce a risk that some other code will misunderstand your responses; when that happens, the blame lies squarely with your implementation, not the client.
Expressed another way: violating the standard doesn't make things "easier"; what it does is move around where the work needs to be done. Abiding the standard is doing your fair share of the work; offloading your share of the work onto your clients is rude.
That said, if you look carefully, there are plenty of spaces where you will find that people do deliberately violate the standards (I see this when working on health checks). The dreadful consequences of violating the standard are not guaranteed.

Use appropriate status codes for appropriate errors. Both SOAP and REST should use 4xx and 5xx where they make sense. If you are looking for a good standard response type for REST, go for application/problem+json, for SOAP use SOAP's standards.
Clients for each should still behave correctly if they get a HTTP error, but don't support/understand the response body.

Related

Differentiating between 404 types

I know the 404 vs 204 debate has been beaten to death, and I understand the argument for using 404 when there is no record in the table corresponding to a REST endpoint request, but it feels like there should be some way of differentiating between "This endpoint is malformed" and "there is no record in the table." For example if I have an endpoint like this:
https://mycloudfront.cloudfront.com/api/my-table/{userId}
Is there a recommended way of configuring error handling on the backend to differentiate between "no resource found because there is no entry for userId" and "no resource found because there is no table named my-table" or "no resource found because there is no cloudfront distribution named mycloudfront"?
I ask, because it would be nice on the frontend to inform the end user whether or not their request did not produce the desired result because they have no data in the table (in which case I would display a message encouraging them to take an action that would generate data) or because something went wrong (in which case I would display an error message).
it would be nice on the frontend to inform the end user whether or not their request did not produce the desired result because they have no data in the table
That's what the response body is for.
Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition. RFC 9110.
Status codes are metadata in the transfer-of-documents-over-a-network domain (Webber, 2011) - the information indicates to general purpose web components (browsers, proxies, caches, spiders....) the semantics (meaning) of the fields and response body (ex: does the message include a representation of a resource or a representation of an error?)
Bespoke HTTP message handlers (and human operators) are expected to look for information in the body (ex: a 404 for a web page returns a picture of a fail whale and a bunch of links to different resources that might clarify what's gone wrong).
You can also leverage ideas like web linking (RFC 8288), if you want to describe relationships between the error and other resources.
Problem Details (RFC 7807) describes a standardized JSON schema for communicating error information, if you want a JSON representation but prefer not to do all of the schema design yourself.
First and foremost, REST has no endpoints but resources.
there should be some way of differentiating between "This endpoint is malformed" and "there is no record in the table."
By "This endpoint is malformed" I guess you probably mean the request issued to the server doesn't conform to the HTTP specification. As voice already mentioned, HTTP status code are coordination metadata for the outcome of the transportation and not necessarily the outcome of your business logic. Of course you need to come up with a mapping for problems you noticed while applying your business logic to the HTTP transport domain.
Unfortunately, REST is polluted with false assumption and believes. Plenty of people seem to think of it as HTTP based CRUD mostly done with JSON payloads. But this is just a very tiny fraction of what REST really is. At its heart it is a technique used in distributed computing to help decouple clients from server to allow the latter to evolve freely in future. Clients on the other hand are build with the inherent design decision of a possible change in mind and therefore get much more robust towards change in the end.
So, how does REST help to decouple clients from servers?
First, the spelling of a URI is not of importance. The URI needs to be a valid one but that's it basically. Clients shouldn't parse the URI or try to extract some knowledge off the URI nor does a URI pattern like /api/user/1 and /api/user/1/stuff mean that both of those URIs are somehow related. That's what link-relations are there for.
Next, in order to teach a client what an URI returned by the server is good for URIs should come with one or multiple link-relation names, which should either be based on registered ones or at least follow the Web Linking extension mechanism, which basically is just a further URI that does not necessarily need to point to a valid resource. Treat it like a predicate in a (SemWeb) ontology.
Use forms similar to HTML, like HAL-forms, JsonForms or Ion, if your server needs further input from clients. Forms also teach clients on what HTTP methods to use, which URI to send the request to, what media-type to encode the request in and of course a description of the properties the resource has and/or the server expects input for. This information is enough to let a client send valid HTTP requests in terms of the transport domain to the server. Note that this does not mean that there won't be any issues then. Requests still might fail to reach the server due to internet outage on whatever end, the request being routed badly and exceed the maximum number of allowed hops and so on but depending on the HTTP method used for sending the request a client might automatically reissue a request once it hit its timeout threshold.
In order to increase interoperability of any peer in a REST ecosystem REST has a strong focus on media types. Think of it as the binding contract between a client and a server which should be negotiated between both of them. This guarantees that both are capable of exchanging "messages" both understand and are able to process. One of the difference to regular RPC services here though is that RPC services are usually restricted to one payload mechanism while REST supports more or less an unlimited amount of payloads, depending on its support for various media-types. Media types are a human-readable description on how payload should be encoded and processed and also contains information, besides the syntax description of allowed elements, a semantic description on the purpose of the respective elements. A payload issued for plain application/json doesn't teach a client really what the properties of the respective JSON objects used in the payload mean nor does it really support URIs in first place. Note however that issuing a plain JSON request to the server is fine if the client was "instructed" that way using a form the client was acting upon. The server here just expects that kind of payload then. Just look at how a typical HTML document is build up and read up on some of the tag definitions that are used within the HTML document and you might get the gist of this paragraph.
Especially about the latter two points Fielding himself was quite vocal about in his famous rant:
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 ...
So, back to the actual question at hand. Is "there is no record in the table" really a business logic error? You could also design it to return what's currently available there and return an empty list. This at least spare you the hazzle of mapping that business error onto the transportation domain in that case.
If you want or need to express a business logic failure to the client you should, as voice also recommended before, look into application/problem+json (or its XML alternative application/problem+xml) which define properties such as type of failure, general title, status and details among others. The respective type the response is issued for may define further properties specific to that type that are part of the payload. I.e. you may define an extension type of http://acme.com/problem/validation and this extension type defines that the payload needs to contain a target-ref property to identify the element that failed the validation check as well as a property for the actual error message.
In the end some general recommendations in terms of REST are:
Design the interactions of client and servers first as if you'd interact with a typical human-focused Web page and then translate the interaction steps onto the application domain. REST in the end is nothing more than a generalized approach for how we humans interact on the Web for decades. REST is basically Web surfing for applications rather than humans. As we humans follow an outlined state machine of i.e. Amazon.com to order some books, computers can do the same. Therefore design the whole interaction between client and server as state machine that clients just follow along and may exit at certain points
Allow servers to teach clients what they need to know using various form-support and use link-relations to set given URIs in context to the current resource

What is the HTTP method for an API that calls another API?

I am writing a service where the client makes an API call to my service, and my service then augments the request payload, then passes it on to another service. For my API, what should the HTTP method be if it's not interacting with a database?
what should the HTTP method be
Key idea: the fact that your server communicates with another API, rather than a database, or a filesystem, is an implementation detail; details of your implementation are not supposed to be leaking into your messages.
Given that the incoming request has a message body; GET, HEAD, DELETE are all right out, because those methods have no defined semantics for a payload.
POST/PUT/PATCH are all possible.
Ideally, you would match the method token that you are using to talk to your back end. This is essentially how a reverse proxy works. You're just playing man in the middle, after all, so it shouldn't be too much of a surprise that the request semantics match.
They don't always, of course - and you might want to inject your own semantics if you find that the API you are calling has made poor method choices in its own design.
When in doubt, it is okay to use POST
One of the REST principles — namely, ‘Layered System’ constraint — implies that:
each component cannot "see" beyond the immediate layer with which they are interacting
So you actually should not make any difference between ‘simple’ and ‘proxied’ API calls.

Can we pass parameters to HTTP DELETE api

I have an API that will delete a resource (DELETE /resources/{resourceId})
THE above API can only tell us to delete the resource. Now I want to extend the API for other use cases like taking a backup of that resource before deleting or delete other dependant resources of this resource etc.
I want to extend the delete API to this (DELETE /resources/{resourceId}?backupBeforeDelete=true...)
Is the above-mentioned extension API good/recommended?
According to the HTTP Specification, any HTTP message can bear an optional body and/or header part, which means, that you can control in your back-end - what to do (e.g. see what your server receives and conventionally perform your operation), in case of any HTTP Method; however, if you're talking about RESTful API design, DELETE, or any other operation should refer to REST API endpoint resource, which is mapped to controller's DELETE method, and server should then perform the operation, based on the logic in your method.
DELETE /resources/{resourceId} HTTP/1.1
should be OK.
Is the above-mentioned extension API good/recommended?
Probably not.
HTTP is (among other things) an agreement about message semantics: a uniform agreement about what the messages mean.
The basic goal is that, since everybody has the same understanding about what messages mean, we can use a lot of general purpose components (browsers, reverse proxies, etc).
When we start trying to finesse the messages in non standard ways, we lose the benefits of the common interface.
As far as DELETE is concerned, your use case runs into a problem, which is that HTTP does not define a parameterized DELETE.
The usual place to put parameters in an HTTP message is within the message body. Unfortunately...
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request
In other words, you can't count on general purpose components doing the right thing here, because the request body is out of bounds.
On the other hand
DELETE /resources/{resourceId}?backupBeforeDelete=true
This has the problem that general purpose components will not recognize that /resources/{resourceId}?backupBeforeDelete=true is the same resource as /resources/{resourceId}. The identifiers for the two are different, and messages sent to one are not understood to affect the other.
The right answer, for your use case, is to change your method token; the correct standard method for what you are trying to do here is POST
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.” -- Fielding, 2009
You should use the "real" URI for the resource (the same one that is used in a GET request), and stick any parameters that you need into the payload.
POST /resources/{resourceId}
backupBeforeDelete=true
Assuming you are using POST for other "not worth standardizing" actions, there will need to be enough context in the request that the server can distinguish the different use cases. On the web, we would normally collect the parameters via an HTML form, the usual answer is to include a request token in the body
POST /resources/{resourceId}
action=delete&backupBeforeDelete=true
On the other hand, if you think you are working on an action that is worth standardizing, then the right thing to do is set to defining a new method token with the semantics that you want, and pushing for adoption
MAGIC_NEW_DELETE /resources/{resourceId}
backupBeforeDelete=true
This is, after all, where PATCH comes from; Dusseault et al recognized that patch semantics could be useful for all resources, created a document that described the semantics that they wanted, and shepherded that document through the standardization process.

How is data sent in REST web services

I am learning about web services. I now have good understanding of SOAP. I have few questions regarding REST web services.
1) DO GET, PUT & POST methods in REST web services work exactly the same way as they work with a simple website.
2) GET , PUT & POST methods in REST web services allows us to send/Receive data(say: tweet in Twitter) between client & the web service. Is this message sent(PUT & POST) & Received(GET) in the Body of the POST/PUT method in XML/JSON/other formats or is the file(in a specific format) sent separately.
3) Are there any Browser tools available to see what is Sent & Received in REST web services.
First of all, clarifying a few things. REST is an architectural style, a set of constraints to guide your structural design decisions. REST is not coupled to any particular underlying protocol, so it's not dependent on HTTP, although it's very common.
Second, keep in mind that REST became a buzzword to refer to almost any HTTP API that isn't SOAP, and most of the so called REST APIs aren't REST at all. Most of them are simple RPC over HTTP. I recommend reading this answer for some clarification on that.
Now, to your questions:
1) DO GET, PUT & POST methods in REST web services work exactly the
same way as they work with a simple website.
The problem with your question is that the only exact definition of how those methods work is the one defined by the RFCs, and a simple website might implement it differently. For instance, PUT isn't allowed to be used for partial updates, but many websites and HTTP APIs do that.
As I said above, REST is protocol independent, but respecting the uniform interface constraint and applying the principle of generality, you should stick to the standard semantics of the underlying protocol as much as possible, which means that if you're using HTTP 1.1, you should stick to the behavior determined in the RFCs 7230 to 7235.
2) GET , PUT & POST methods in REST web services allows us to
send/Receive data(say: tweet in Twitter) between client & the web
service. Is this message sent(PUT & POST) & Received(GET) in the Body
of the POST/PUT method in XML/JSON/other formats or is the file(in a
specific format) sent separately.
The format is established in a previous contract between the client and server -- usually in the documentation -- and it's handled during the request using the Accept and Content-Type headers. For instance, if a client wants JSON response, it sends the Accept: application/json header. If the server can't respond with JSON, it should fail with 406 Not Acceptable.
Keep in mind that in an actual REST webservice, you don't use a generic media-type like application/json since that says absolutely nothing about the content other than how to parse it. You should have more specific media-types for your resources, and focus your documentation on those. For instance, an User resource in JSON format can have a custom media-type like application/vnd.mycompany.user.v1+json.
3) Are there any Browser tools available to see what is Sent &
Received in REST web services
In Google Chrome you can use the developer tools, or some client like this or this. You can also use a command line client like curl.
Also, keep in mind that it should be pretty easy to drop-in a generic html+javascript client into a real REST API to make it navigable with a browser. Here is an example of a REST API using HAL+JSON and a generic client.
https://api-sandbox.foxycart.com/hal-browser/browser.html#/
1) Yes, REST functions pretty much exactly the same as a normal HTTP website, for example, GET would retrieve data without changing the state of the server and POST would send data to the web service as a new 'Object', and PUT would modify an existing 'Object'
2) You would enclose the data to be sent inside the body of the request for POST and it would return data back in the body. GET does not accept any data in the body (and you would specify it as part of the path/query parameters ie http://service.com/rest/directory/user1?param=something) but would return the results of the query inside the body. POST would require a message to be posted in one of the forms specified as accepted, most usually JSON. Specifying the Content-Type would indicate to the web server what type of data you are sending and the Accept header would indicate what type you wish your response to be in.
3) In Google Chrome you can use the Developer Tools (Ctrl+Shift+I in Windows) and go on the Network tab to see what is sent and received as a page is loading/performing tasks. You can use DHC or RestEasy to send your own custom requests to REST Services through a GUI, or cURL to do this through a command line
DO GET, PUT & POST methods in REST web services work exactly the same way as they work with a simple website?
yes. they are same anywhere we are using http. read this article specially Request Method section
GET , PUT & POST methods in REST web services allows us to send/Receive data(say: tweet in Twitter) between client & the web service. Is this message sent(PUT & POST) & Received(GET) in the Body of the POST/PUT method in XML/JSON/other formats.
yes they are generally in these formats but can be in any depending on ur requirement.
read this ans for better understanding of content-type and headers in general
Are there any Browser tools available to see what is Sent & Received in REST web services.
as mentioned in one of the comments. Postman is an awesome chrome extension. I generally preffer fiddler over Postman but it is not a in browser tool.

WCF Rest - what are the best practices?

Just started my first WCF rest project and would like some help on what are the best practices for using REST.
I have seen a number of tutorials and there seems to be a number of ways to do things...for example if doing a POST, I have seen some tutorials which are setting HttpStatusCodes (OK/Errors etc), and other tutorials where they are just returning strings which contain result of the operation.
At the end of the day, there are 4 operations and surely there must be a guide that says if you are doing a GET, do it this way, etc and with a POST, do this...
Any help would be appreciated.
JD
UPDDATE
Use ASP.NET Web API.
OK I left the comment REST best practices: dont use WCF REST. Just avoid it like a plague and I feel like I have to explain it.
One of the fundamental flaws of the WCF is that it is concerned only with the Payload. For example Foo and Bar are the payloads here.
[OperationContract]
public Foo Do(Bar bar)
{
...
}
This is one of the tenants of WCF so that no matter what the transport is, we get the payload over to you.
But what it ignore is the context/envelope of the call which in many cases transport specific - so a lot of the context get's lost. In fact, HTTP's power lies in its context not payload and back in the earlier versions of WCF, there was no way to get the client's IP Address in netTcpBinding and WCF team were adamant that they cannot provide it. I cannot find the page now but remember reading the comments and the MS guys just said this is not supported.
Using WCF REST, you lose the flexibility of HTTP in expressing yourself clearly (and they had to budge it later) in terms of:
HTTP Status code
HTTP media types
ETag, ...
The new Web API, Glenn Block is working addresses this issue by encapsulating the payload in the context:
public HttpResponse<Foo> Do(HttpRequest<Bar> bar) // PSEUDOCODE
{
...
}
But to my test this is not perfect and I personally prefer to use frameworks such as Nancy or even plain ASP NET MVC to expose web API.
There are some basic rules when using the different HTTP verbs that come from the HTTP specification
GET: This is a pure read operation. Invocation must not cause state change in the service. The response to a GET may be delivered from cache (local, proxy, etc) depending on caching headers
DELETE: Used to delete a resource
There is sometimes some confusion around PUT and POST - which should be used when? To answer that you have to consider idempotency - whether the operation can be repeated without affecting service state - so for example setting a customer's name to a value can be repeated multiple times without further state change; however, if I am incrementing a customer's bank balance this cannot be safely be repeated without further state change on the service. The first is said to be idempotent the second is not
PUT: Non-delete state changes that are idempotent
POST: Non-delete state changes that are not idempotent
REST embraces HTTP - therefore failures should be communicated using HTTP status codes. 200 for success, 201 for creation and the service should return a URI for the new resource using the HTTP location header, 4xx are failures due to the nature of the client request (so can be fixed by the client changing what they are doing), 5xx are server errors that can only be resolved server side
There's something missing here that needs to be said.
WCF Rest may not be able to provide all functionality of REST protocol, but it is able to facilitate REST protocol for existing WCF services. So if you decide to provide some sort of REST support on top of the current SOAP/Named pipe protocol, it's the way to go if the ROI is low.
Hand rolling full blown REST protocol maybe ideal, but not always economical. In 90% of my projects, REST api is an afterthought. Wcf comes in quite handy in that regard.