{"id":5991,"date":"2017-03-14T10:38:52","date_gmt":"2017-03-14T10:38:52","guid":{"rendered":"https:\/\/9series-blog.staging9.com\/?p=5991"},"modified":"2026-03-03T10:44:30","modified_gmt":"2026-03-03T10:44:30","slug":"best-practices-for-designing-restful-apis","status":"publish","type":"post","link":"https:\/\/www.9series.com\/blog\/best-practices-for-designing-restful-apis\/","title":{"rendered":"Best Practices for Designing Restful APIs"},"content":{"rendered":"<p><a href=\"https:\/\/9series-blog.staging9.com\/wp-content\/uploads\/2017\/03\/Best-Practices-for-Designing-Restful-APIs1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2056\" src=\"https:\/\/9series-blog.staging9.com\/wp-content\/uploads\/2017\/03\/Best-Practices-for-Designing-Restful-APIs1.jpg\" alt=\"Best-Practices-for-Designing-Restful-APIs\" width=\"800\" height=\"500\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>A deliberately designed RESTful API describes relationships, schema, resources and structure which will be easily available by the native apps.<\/p>\n<p>When you develop &amp; deploy any web API, consider requirements for the physical environment to host APIs and the way it&#8217;s developed rather than the logical structure.<\/p>\n<p><em>API serves functionality of an application for other clients to use. With the use of API, applications interact with each other and yield output without any user knowledge.<\/em><\/p>\n<p>Generally, web applications should have RESTful JSON APIs. REST stands for \u201cRepresentational State Transfer\u201d a fundamental style and approach to communications and used to develop scalable web services. JSON is lightweight and is in a readable format and it is used to structure the data.<\/p>\n<p><a href=\"https:\/\/9series-blog.staging9.com\/wp-content\/uploads\/2017\/03\/API_arch1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2057\" src=\"https:\/\/9series-blog.staging9.com\/wp-content\/uploads\/2017\/03\/API_arch1.jpg\" alt=\"API_arch\" width=\"800\" height=\"281\" \/><\/a><\/p>\n<p>Here are some pragmatic best practices to build a RESTful APIs using ASP.NET.<\/p>\n<p><strong>Use HTTP methods:<\/strong><\/p>\n<ul>\n<li>Use URLs to specify resources and HTTP methods to specify what to do with this resources.<\/li>\n<li><span style=\"font-weight: bold\">Read:<\/span> Use GET to retrieve relevant resources. The GET method has a read-only semantic and can catch calls perfectly.<\/li>\n<li><span style=\"font-weight: bold\">Create:<\/span> Use POST to create new resources.<\/li>\n<li><span style=\"font-weight: bold\">Update:<\/span> Use PUT to update existing resources.<\/li>\n<li><span style=\"font-weight: bold\">Delete:<\/span> Use DELETE to delete existing resources.<\/li>\n<\/ul>\n<p><strong>Use HTTP status code to handle errors:<\/strong><\/p>\n<p>API should give response with suitable status code and appropriate message in the response body.<\/p>\n<p>There are many HTTP status codes, some are listed here:<\/p>\n<p>200 OK \u2013 [GET]<br \/>\n201 CREATED \u2013 [POST\/PUT\/PATCH]<br \/>\n204 NO CONTENT \u2013 [DELETE]<br \/>\n304 NOT MODIFIED<br \/>\n400 INVALID REQUEST \u2013 [POST\/PUT\/PATCH]<br \/>\n401 UNAUTHORIZED<br \/>\n403 FORBIDDEN<br \/>\n404 NOT FOUND<br \/>\n500 INTERNAL SERVER ERROR<\/p>\n<p>Here is an example for some HTTP methods &amp; status code to use to perform CRUD operation using APIs<\/p>\n<table class=\"table alignleft\" style=\"width: 100%\" cellspacing=\"0\" cellpadding=\"0\">\n<thead>\n<tr>\n<th style=\"width: 20%\">HTTP Verb<\/th>\n<th style=\"width: 20%\">CRUD<\/th>\n<th style=\"width: 25%\">Entire Collection (e.g. \/customers)<\/th>\n<th style=\"width: 25%\">Specific Item (e.g. \/customers\/{id})<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>POST<\/td>\n<td>Create<\/td>\n<td>201 (Created)<\/td>\n<td><a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_status_codes\" target=\"_blank\">404 (Not Found)<\/a>,<\/td>\n<\/tr>\n<tr>\n<td>GET<\/td>\n<td>Read<\/td>\n<td style=\"text-align: left\">200 (OK)<\/td>\n<td><a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_status_codes\" target=\"_blank\">200 (OK)<\/a><\/td>\n<\/tr>\n<tr>\n<td>PUT<\/td>\n<td>Update\/Replace<\/td>\n<td>404 (Not Found)<\/td>\n<td><a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_status_codes\" target=\"_blank\">200 (OK) or 204 (No Content). 404 (Not Found)<\/a><\/td>\n<\/tr>\n<tr>\n<td>PATCH<\/td>\n<td>Update\/Modify<\/td>\n<td>404 (Not Found)<\/td>\n<td><a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_status_codes\" target=\"_blank\">200 (OK) or 204 (No Content). 404 (Not Found)<\/a><\/td>\n<\/tr>\n<tr>\n<td>DELETE<\/td>\n<td>Delete<\/td>\n<td>404 (Not Found)<\/td>\n<td><a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_status_codes\" target=\"_blank\">200 (OK). 404 (Not Found)<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"text-align: left\"><strong>HTTP method Overriding:<\/strong><\/p>\n<p style=\"text-align: left\">Some proxies don\u2019t support PUT or DELETE. This is because of browser or really tense corporate firewall. So to overcome these limitations, API needs a way to override HTTP method and we can call it \u201ctunnel\u201d also. So that means a header says \u201cSeriously!!..I got here via POST, but I will allow you to use this one instead.\u201d To achieve this functionality, use &#8220;X-HTTP-Method-Override: PUT&#8221; as a header.<\/p>\n<p style=\"text-align: left\"><strong>Simplify Associations:<\/strong><\/p>\n<p style=\"text-align: left\">Data \/ Resources always have relationships with other resources. We&#8217;re using HTTP verbs to operate on the resources and collections. For example, city belongs to country. To get all the cities of specific country, or to create new city for that country, use GET or POST method. Representation of these associations in URL are like: \u201cGET country\/21\/city\u201d. This URL will return all cities of specific country and using \u201cPOST country\/21\/city\u201d It will create city and relationships between specific country.<\/p>\n<p style=\"text-align: left\"><strong>Use the Query String (?) for Optional or Complex Parameter:<\/strong><\/p>\n<p style=\"margin-top: 20px;text-align: left\">Always keep URL short and simple. Select one base URL for resource and move complexity or optional parameters to query string.<br \/>\n<strong> EG. \u201cGET \/students\/standard=12&amp;subject=physics\u201d<\/strong><\/p>\n<p style=\"text-align: left\"><strong>Filtering, Sorting and Paging for Collections:<\/strong><\/p>\n<p style=\"text-align: left\">Use a unique query parameter for all fields or a query language for filtering.<\/p>\n<ul>\n<li><strong>Filtering<\/strong><span style=\"font-weight: bold\">:\u00a0<\/span>GET \/students?class=12 will return students of class 12th.<br \/>\nGET \/students?marks<\/li>\n<li><span style=\"font-weight: bold\">Sorting:\u00a0<\/span>Allow ascending and descending sorting over multiple fields.<br \/>\nGET \/students?medium=English<\/li>\n<li><span style=\"font-weight: bold\">Paging:\u00a0<\/span>Use limit and offset. It is flexible for the user and common in leading databases. To send the total entries back to the user, use custom HTTP header : X-Total-Count links to the previous or next page should be provided in the HTTP header link as well.<\/li>\n<li><span style=\"font-weight: bold\">API Versioning:<\/span> Make the API version mandatory and do not release an unversioned API and avoid dot notation such as 2.5.<br \/>\nVersioning API will help to emphasize rapid and invalid block requests from hitting updated endpoints. It will likewise help smoothly over any major API version transitions to continue old API versions for a time being.<br \/>\nThere are lot of mixed opinions regarding API version that it should be managed through URL or in a header; Academically speaking, it should be in a header. However, the version needs to be in the URL to ensure browser exploration of the resources across versions.<br \/>\nThe URL has a significant version number (v1), but the API has date based sub-versions which can be determined using a custom HTTP request header. In this case, the significant version provides structural stability of the API as a whole, while the sub-version accounts for smaller changes (field deprecations, endpoint changes, etc).<\/li>\n<\/ul>\n<p style=\"text-align: left\"><strong>Documenting your REST API:<\/strong><\/p>\n<p style=\"text-align: left\">As a developer, make use of API documentation to understand how to utilize a service on which we are depending on. Getting started from the scratch is always the biggest challenge and time consuming, so I greatly appreciate those APIs that are very well-documented. Some of them even make it fun to learn to make effective and easy understandable document.<\/p>\n<p style=\"text-align: left\">Below are the points that are good to have in your document.<\/p>\n<ul>\n<li><span style=\"font-weight: bold\">Title:<\/span> Additional information about your API. Try to use verbs.<\/li>\n<li><span style=\"font-weight: bold\">URL:<\/span> The URL Structure (path only, no root url)<\/li>\n<li><span style=\"font-weight: bold\">Method:<\/span> The request type<\/li>\n<li><span style=\"font-weight: bold\">URL Params:<\/span> If URL params exist, specify them in accordance with name mentioned in URL section. Separate the section into Optional and Required.<code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">Required:<br \/>\nid=[integer]<br \/>\nOptional:<br \/>\nphoto_id=[alphanumeric]<br \/>\n<\/code><\/li>\n<li><span style=\"font-weight: bold\">Data Params:<\/span> If the request type is POST, what should be the body payload look like? URL Params rules apply here too.<\/li>\n<li><span style=\"font-weight: bold\">Success Response:<\/span> What should be the status code and is there any return data? This is useful when people need to know what their callbacks should expect! <code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">Code: 200<br \/>\nContent: { id : 12 }<br \/>\n<\/code><\/li>\n<li><span style=\"font-weight: bold\">Error Response:<\/span> Most endpoints have many ways to fail. From unauthorized access, to wrongful parameters etc. All of those should be listed here. It might seem repetitive, but it helps prevent assumptions from being made. <code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">Code: 401 UNAUTHORIZED<br \/>\nContent: { error : \"Log in\" }<br \/>\n<\/code><\/li>\n<li><span style=\"font-weight: bold\">Sample Call:<\/span> A sample call to your endpoint in a runnable format ($.ajax call or a curl request) &#8211; this makes life easier and more predictable.<\/li>\n<\/ul>\n<p style=\"text-align: left\"><span style=\"font-weight: bold\">Example:<\/span><\/p>\n<ul>\n<li>City: Returns JSON data about a city.<\/li>\n<li>URL: <code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">City\/Cid<br \/>\n<\/code><\/li>\n<li>Method:<code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">GET<br \/>\n<\/code><\/li>\n<li>URL Params Required:<code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">Cid=[integer]<br \/>\n<\/code><\/li>\n<li>Data Params:<code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">None<br \/>\n<\/code><\/li>\n<li>Success Response:<code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">Code: 200<br \/>\nContent: { Id: 2, name : \"Delhi\" }<br \/>\n<\/code><\/li>\n<li>Error Response:<code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\">Code: 404 NOT FOUND<br \/>\nContent: { Response : null }<br \/>\n<\/code><\/li>\n<li>Sample Call:<code style=\"margin-top: 20px;font-size: 13px;line-height: 18px;color: #146c7c\"> $.ajax({<br \/>\nurl: \"\/City\/108\",<br \/>\ndataType: \"json\",<br \/>\ntype : \"GET\",<br \/>\nsuccess : function(r) {<br \/>\nconsole.log(r);<br \/>\n} });<br \/>\n<\/code><\/li>\n<\/ul>\n<p style=\"text-align: left\"><strong>Testing:<\/strong><\/p>\n<p style=\"text-align: left\">There are a lot of tools available in the market like Soap UI, JMeter, etc. But building continuous Integration with these tools can be a challenging task. It can be troublesome for developers to run these tools. So, the solution must be written in developer&#8217;s language.<\/p>\n<p style=\"text-align: left\">Visual Studio has NuGet Package Called RestSharp and Newtonsoft JSON which makes the task easier for testing Rest API in a Black Box Manner.<\/p>\n<p style=\"text-align: left\">RestSharp can send an API Get, PUT, Post, Delete and Patch Request and can get the response back from the API. In the Response, we can Check API for proper status Code, status Message, an assertion for specific JSON or XML Data.<\/p>\n<p style=\"text-align: left\">Newtonsoft.json can deserialize JSON c#, which can be useful to get a JSON &#8220;Authentication Token&#8221; from the response body of the request. It helps to chain the request and makes life easy.<\/p>\n<p style=\"text-align: left\"><strong>Steps for Solution:<\/strong><\/p>\n<ul>\n<li>Open The Visual Studio<\/li>\n<li>Create a New Console Application in the Visual Studio<\/li>\n<li>Add NuGet RestSharp, Newtonsoft.json Package to the Solution<\/li>\n<li>Write a Post Request<\/li>\n<li>Deserialize the JSON Request and fetch the authentication token from the response of the API<\/li>\n<li>Assert the API for the Status Code and Status Response.<\/li>\n<li>After getting token from the first API (login API) it can be passed to another API as well<\/li>\n<\/ul>\n<p style=\"text-align: left\">These are the basic things to be taken care to design RESTful API structure; Stay tuned for our next article very soon.<\/p>\n<p style=\"text-align: left\">We <a href=\"https:\/\/www.9series.com\/services\/asp-dot-net-development.html\" target=\"_blank\">9series<\/a>, as an organization always try to serve best quality work to our esteemed clients; our expert team of engineers takes care of all small entities and requirements for the physical environment to host APIs and the way it&#8217;s constructed.<\/p>\n<p style=\"text-align: left\">\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; A deliberately designed RESTful API describes relationships, schema, resources and structure which will be easily available by the native apps. When you develop &amp; deploy any web API, consider&#8230;<\/p>\n","protected":false},"author":1,"featured_media":5992,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"dsgo_overlay_header":false,"dsgo_overlay_header_text_color":"","dsgo_overlay_skip_top_bar":false,"_designsetgo_exclude_llms":false,"footnotes":""},"categories":[1429],"tags":[1972,1973,1923,1864,1974,1975,1976],"class_list":["post-5991","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft","tag-net-developers","tag-net-development","tag-asp-net","tag-best-net-mvc-developers-in-india","tag-http-methods","tag-restful-api","tag-web-applications"],"_links":{"self":[{"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/posts\/5991","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/comments?post=5991"}],"version-history":[{"count":1,"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/posts\/5991\/revisions"}],"predecessor-version":[{"id":5994,"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/posts\/5991\/revisions\/5994"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/media\/5992"}],"wp:attachment":[{"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/media?parent=5991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/categories?post=5991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.9series.com\/blog\/wp-json\/wp\/v2\/tags?post=5991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}