ASP.NET WEB API BEST PRACTICESHere are some of ASP.NET WEB API best practice that should be follow while developing RESTful applications on the .NET Framework:
CREATE LOGICAL RESOURCES AND USE RESTFUL URLS
The key principles of REST involve separating your API into logical resources. These resources are manipulated using HTTP requests where the method (GET, POST, PUT, PATCH and DELETE) has specific meaning.
USE NOUNS NOT VERBS FOR RESOURCE
One major rule of API design is to use Nouns for resources. Nouns make URL more meaningful and make more sense from the perspective of the API consumer.For example:
GET /ticketing/1
Instead of using ticketing in URL use tickets.
GET /tickets/1
Should reveal action
THE ENDPOINT NAME SHOULD BE PLURAL
Try to keep the URL format consistent and always use a plural. If possible, try to avoid odd pluralization like person/people and goose/geese.
TWO BASE URLS PER RESOURCE
Create two base URLs per resource, one for multiple values and one for the specific value.
For Example: To retrieves all tickets
GET /tickets
To retrieves ticket with Id 1
GET /tickets/1
RESOURCE ASSOCIATIONS
Your APIs should be very intuitive when you're developing them for associations. The following URL intuitively suggests that it's requesting a training that's delivered by a trainer with an ID of 14 and training with ID 114:
GET /trainers/14/trainings
We have traversed two levels in this URL. One level is the trainer, and the second level is the training that the trainer is providing.
URL COMPLEXITY
It's highly recommended to use a query string to reduce the complexity of a URL that has several different associations. The following shows complicated and unintuitive to the user:
GET /trainers/12/trainings/11/zip/75080/city/richardson/state/tx
The following shows a better way to write a query string:
GET /trainers/12/trainings/11?zip=75080&city=richardson&state=tx
ERROR FORMAT
An error format is very important and there's a need to have a particular error format across the board in a company. Let's consider an error format such as the following:
{
"http_code": "401",
"message": "Authentication needed",
"internal_error_code" : "123",
"Error" : http:// chanderdhall.com/wiki/errors/123
}
The property names such as "internal_error_code" can be made shorter such as "code." The reasons that these property names are longer are so that they are also self-explanatory. In the example above, 401 is nothing but the HTTP error code and 123 is an internal error code details to which could be found at the details_url. This has an added advantage for the user to understand the error better.
CREATE & UPDATE SHOULD RETURN A RESOURCE REPRESENTATION
In case of a POST that resulted in a creation, use a HTTP 201 status code and include a Location header that points to the URL of the new resource. And in case of PUT and PATCH that resulted in an update, return the resource representation in response. This prevents an API consumer from having to hit the API again for an updated representation.
PREFER TO USE JSON RESPONSE OVER XML RESPONSE
From the point of view of API consumer, JSON response should be used instead of using XML because XML is verbose, hard to parse, hard to read and in term of response size there is big difference between JSON and XML.
COMPRESSION
Enable gzip compression on IIS to compress your API output as it plays a major role in bandwidth savings.
VERSIONING
Always version your API. Versioning helps you iterate faster and prevents invalid requests from hitting updated endpoints. It also helps smooth over any major API version transitions as you can continue to offer old API versions for a period of time.
RESULT FILTERING AND SORTING
- Filtering: Use a unique query parameter for each field that implements filtering. For example a request like : GET /tickets?state=open
- Sorting: A generic parameter sort can be used to describe sorting rules. Accommodate complex sorting requirements by letting the sort parameter take in list of comma separated fields, each with a possible unary negative to imply descending sort order. For Examples:
GET /tickets?sort=-priority - Retrieves a list of tickets in descending order of priority.
GET /tickets?sort=-priority,created_at - Retrieves a list of tickets in descending order of priority. Within a specific priority, older tickets are ordered first.
LIMITING WHICH FIELDS ARE RETURNED BY THE API
The API consumer doesn't always need the full representation of a resource. The ability select and chose returned fields goes a long way in letting the API consumer minimize network traffic and speed up their own usage of the API.
Use fields query parameter that takes a comma separated list of fields to include. For example, the following request would retrieve just enough information to display a sorted listing of open tickets:
GET /tickets?fields=id,subject,customer_name,updated_at&state=open&sort=-updated_at
DON'T USE AN ENVELOPE
If you want to send extra information in response like pagination data (total pages, current page, etc.) do not use envelop instead use response header for sending extra information.
JSON ENCODED POST, PUT & PATCH BODIES
Use JSON encoded bodies for POST, PUT and PATCH. In this case it should also require the Content-Type header be set to application/json otherwise it will throw a 415 Unsupported Media Type HTTP status code.
DOCUMENT YOUR API
Documentation of API is necessary. Document is the one main mean through which consumer can understand your API and use it. The document should show examples of complete request/response cycles. Preferably, the requests should be paste-able. You can use Swagger to document your WEB API.
HTTP STATUS CODES
HTTP defines a bunch of meaningful status codes that can be returned from your API. These can be leveraged to help the API consumers route their responses accordingly.
- 200 OK - Response to a successful GET, PUT, PATCH or DELETE. Can also be used for a POST that doesn't result in a creation.
- 201 Created - Response to a POST that results in a creation. Should be combined with a Location header pointing to the location of the new resource
- 204 No Content - Response to a successful request that won't be returning a body (like a DELETE request)
- 304 Not Modified - Used when HTTP caching headers are in play
- 400 Bad Request - The request is malformed, such as if the body does not parse
- 401 Unauthorized - When no or invalid authentication details are provided. Also useful to trigger an auth popup if the API is used from a browser
- 403 Forbidden - When authentication succeeded but authenticated user doesn't have access to the resource
- 404 Not Found - When a non-existent resource is requested
- 405 Method Not Allowed - When an HTTP method is being requested that isn't allowed for the authenticated user
- 410 Gone - Indicates that the resource at this end point is no longer available. Useful as a blanket response for old API versions
- 415 Unsupported Media Type - If incorrect content type was provided as part of the request
- 422 Unprocessable Entity - Used for validation errors
- 429 Too Many Requests - When a request is rejected due to rate limiting