RESTFul Webapi Implementation Guidelines

REST-WebApi Implementation Guidelines

 

Introduction

As we are going into the era where all devices needs to be connected with the server there is a need to build an API that is easy to use and all devices speaks the same langugage.

What is REST?

Representational State Transfer. It relies on a stateless, client-server, cacheable communications protocol — and in virtually all cases, the HTTP protocol is used.

What is Hypermedia?

In layman term, when the REST response comes back then it should include some webapi resources as a reference for the client. This way the client can get to know some valid URI that can be called by the client.

  • Method of self-describing messages
  • Hypermedia as The Engine of Application State == HATEOAS
  • Hypermedia can create dynamic, self-documenting APIs
  • But you can be a great API without HATEOAS

rest

Web Services Vs REST

The concept of API is in development industry since COM, however, what has been changed now is how easy this API is available for different devices.

COM       Limitation: COM should be packaged along with the program. COM is accessible for only specific programming langugage, which means C++ dll is not directly accessible to Java.
 DCOM   Limitation: A proxy needs to be installed on local machine. Again a compatiblity issue, permission headache.
ASMX    Web service that is accessible through HTTP protocal and the client only needs to know how to call through a proxy that uses SOAP as a message protocol.
SVC Client still needs to have a knowledge to interpret SOAP.

Why Web service era is drying… Web service calls require a standard to be followed such as SOAP. Not all devices knows about these standards. This adds a complexity to provide a library at client level that can communicate in SOAP message format and web service can be connected. In case of REST WebApi it uses http. Thus, it has less overhead as compare to previous technology. Now what it means to your coding that your functions are available as is from Mobile to a Desktop. All you need is HTTP to call, which is available even in 20 $ mobile phones.

Should you use REST?
  • REST or REST-ful APIs are easy to consume and maintain
  • If your API does not fit the Resource Model, RPC or custom APIs are fine
  • Your new development should starts from REST principle and if does not fit then please proceed with the old procedure.

What will you learn here?

Idea behind this article  is to give you guidelines on what should be done for making a a good Web API. This document is listing some points that I have learnt and implemented (some :-)) for WebApi architecture. You can implement these rule in any programming language. Let us understand these rules.

Rules

1. » Don’t use verb as a part of the URL. So rather than saying that /todos/update it should be URL: /todos METHOD: POST or PUT.

The main reason of not using verb is because as the project extend there are too many URI and it is hard to main these URI. Thus, it makes it difficult to manage your API.

1.1» Use Identifiers to locate individual items in URIs. It does not have to be internal key.

e.g. (internal key)
http://api.yourcompany.com/customers/23

or (non internal key - however unique identifier to determine that single entity)

http://api.yourcompany.com/customers/283473-asdf923-asdf2

1.2» Use either Plural or Singular noun. However, don’t mix it.

Preferred Preferred Not Preferred
/polls/23 /poll/23 /polls/23
 /todos/2384  /todo/2384  /todo/2384

2. » Concrete is Good over Abstract; so instead of saying /items/23 it should says the type of items like /cars/23

3.» Don’t use query string (?) in the URL, where possible; Set Association resources/id/resources through url.

http://...api/Customers/1/orders
http://...api/customers/1/payments

4.» Use pre defined HTTP status code in your returned header of Api methods. refer available HTTP code at http://en.wikipedia.org/wiki/Http_error_codes

5.» You should also give an option to supress the code by giving an optional parameter which will force API to always return 200. suppress_response_codes. /customers/1? suppress_response_codes=true 

Response should be:

HTTP status code: 200 {"error":"Could not authenticate you."}

6.»  Make the version mandatory. Specify the version with a ‘v’ prefix. But keep in mind that API version is not product version. There are 4 types to implement Versioning:

  • Version as a part of URL – The main drawback is maintaining client on url change.If you are defining URL based version then move it all the way to the left in the URL so that it has the highest scope (e.g. /v1/customers).
  • Version as a part of Querystring – Same drawback as above.
  • Version as Content Type in Accept Header – The main drawback of this approach is it adds complexity implementing custom header on all platform. It can also encourage increased versioning which cause more code churning.e.g. Accept : vnd.api.v1.customer
  • Version as Custom Header – Same drawback as Content Type.e.g. x-api-version: 2 or  x-api-version: 10-07-2014

Whichever way you go, use a simple ordinal number; Don’t use the dot notation like v1.2; Before obsoleting previous versions give developers at least one cycle to react.

7.» Implement partial response; Partial response allows you to give developers just the information they need.

  • Implement Partial GET
  • Implement Partial Patch

8. » Make it easy for developers to paginate objects in a database; Use limit and offset to make it easy for developers to paginate objects.

9.» Accept different format and content negotiation is a Best practice. Use Accept header to determine which formats are allowed.

GET api/customers/1 HTTP/1.1
Accept: application/json, text/xml
Host: localhost...

10. »  Use JSON as a default return type, following Javascript camelCasing conventions for naming attributes.

e.g. {"firstName":"Joe","lastName":"Public"}

11.» Standard place to host is api.xxx.com and if the request is coming from the browser, then redirect it to developers.xxx.com. Also, redirect any request coming for dev, developer to developers.xxx.com

12.» On successful update, return 200 (or 204 if not returning any content in the body) from a PUT. If using PUT for create, return HTTP status 201 on successful creation.

13.» It is strongly recommended to use POST for non-idempotent requests. POST is neither safe or idempotent. It is therefore recommended for non-idempotent resource requests.

14.» PUT vs POST for Creation In short, favor using POST for resource creation. Otherwise, use PUT when the client is in charge of deciding which URI (via it’s resource name or ID) the new resource will have: if the client knows what the resulting URI (or resource ID) will be, use PUT at that URI. Otherwise, use POST when the server or service is in charge of deciding the URI for the newly-created resource. In other words, when the client doesn’t (or shouldn’t) know what the resulting URI will be before creation, use POST to create the new resource.

15.» Choose CORS whenever and wherever possible.

16.» Non-Resource API

  • Be sure that the user can tell it is a different type of operation
  • Be pragmatic and make sure that these parts of your API are documented
  • Don’t use them as an execute to build a RPC API
e.g.
http://...api/calcualateTax?state=GA&total=149.99
http://...api/restartServer?

17.» It is recommended to return an Entity Tag (ETag) header for each GET (read) operation. It should support Week Tag, starts with W/ and supports Strong Tag. if-None-Match header key is used for specifying the ETag value.

GET: /api/customers/1 HTTP /1.1
Accept: application/json, text/xml
Host: localhost
If-None-Match: 823748374783

Request response should return 304 status code.

18.» Protect your Api

  • SSL is almost always appropriate.
  • Secure the API itself using:
    • Cross Origin Security:
    1. JSON with Padding (JSON)  – not recommended coz the callback has to be maintained.
    2. Cross Domain Resource Sharing (CORS) –

19.» Authorization & Authentication 1. Authorization – Use API Keys 2. Authentication  – Options:

    • Website security such as Form, Windows Auth, 1st Party Developer (internal auth.)
    • Use OAuth 3rd party Developer (external auth.)

In the next series of post, I will explain & implement these rules with the help of .NET WEB API programming language.    stay tuned…. Connect with me: View Amit Malhotra's profile on LinkedIn.

An introduction to Gulp Build System

What is Gulp?

Just like Grunt, which is a build tool for front-end web development, Gulp is a new block that runs predefined tasks on static files such as CSS, HTML, Javascript, images. Some of these tasks includes:

  • minimise files size
  • watch file changes and automate the deployment

What is the major difference between Grunt and Gulp?

  • Grunt plug-ins often perform multiple tasks where as Gulp plug-ins are designed to do one thing only; it is clean and neat.
  • Grunt requires plug-ins for basic functionality such as file watching; Gulp has them built-in.
  • Grunt uses JSON-like data configuration files; Gulp uses leaner, simpler JavaScript code. You don’t create multiple configuration files in Gulp for each task like in Grunt.

How to use Gulp?

I have recorded a video about that explains you about:

  1. How to Install Gulp
  2. How to Install Gulp Plugins
  3. How to find Plugins
  4. How to define Gulp tasks
  5. How to execute bunch of tasks
  6. How to watch changes in static resources and execute tasks automatically.

 

 

 

 

References

  • http://www.smashingmagazine.com/2014/06/11/building-with-gulp/

 

Foxit PDF adapted by Google Chrome

Google has announced to use FoxIT PDF libraries through which you can manipulate PDF operation at browser level.

Indeed, it will further push us to develop software that are specific to Google platform. However, it will be good to see how others, like IE Firefox, will cop up with challenges that will push them to extend support of such features into their browsers as well.

I have been playing around with FoxIT. Overall I could see it is a nice & clean sdk that works in different platform. It can also work with encrypted form.

For .net developers there is a piece of samples available directly from the link:

http://cdn01.foxitsoftware.com/pub/foxit/sdk/net/1.x/1.0/FoxitPDFSDKForNET102_enu.zip

The main problem that I find with such type of SDK is that you have to create even a table through coding. If you want to attach chart, graphs in your pdf then things can go too much of writing. That is the main reason that I am no convinced to for for this product or develop something that is specific to the browser.

Now what could be the solution?

The solution that I recommend to my client is to go through RDLC, which is free (technically not) and it is a Microsoft Product, which is easy to design as well.

Here is the sample code that I can guess solve the problem of generating PDF from RDCL.

Warning[] warnings;

string[] streamIds;
string mimeType = string.Empty;
string encoding = string.Empty;
string extension = string.Empty;
DataSet dsGrpSum, dsActPlan, dsProfitDetails,
dsProfitSum, dsSumHeader, dsDetailsHeader, dsBudCom = null;

//This is optional if you have parameter then you can add parameters as much as you want
ReportParameter[] param = new ReportParameter[5];
param[0] = new ReportParameter("Report_Parameter_0", "1st Para", true);
param[1] = new ReportParameter("Report_Parameter_1", "2nd Para", true);
param[2] = new ReportParameter("Report_Parameter_2", "3rd Para", true);
param[3] = new ReportParameter("Report_Parameter_3", "4th Para", true);
param[4] = new ReportParameter("Report_Parameter_4", "5th Para");


DataSet dsData= "Fill this dataset with your data";
ReportDataSource rdsAct = new ReportDataSource("RptActDataSet_usp_GroupAccntDetails", dsActPlan.Tables[0]);
ReportViewer viewer = new ReportViewer();
viewer.LocalReport.Refresh();
viewer.LocalReport.ReportPath = "Reports/AcctPlan.rdlc"; //This is your rdlc name.
viewer.LocalReport.SetParameters(param);
viewer.LocalReport.DataSources.Add(rdsAct); // Add datasource here

// NOTE: You can also pass first parameter as :Excel.
byte[] bytes = viewer.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamIds, out warnings);
// byte[] bytes = viewer.LocalReport.Render("Excel", null, out mimeType, out encoding, out extension, out streamIds, out warnings);

Response.Buffer = true;
Response.Clear();
Response.ContentType = mimeType;
Response.AddHeader("content-disposition", "attachment; filename= filename" + "." + extension);
Response.OutputStream.Write(bytes, 0, bytes.Length); // create the file
Response.Flush(); // send it to the client to download
Response.End();

In conclusion, I will give it a go with generating PDF through SDK if I don’t have an access to RDLC technology. If you want to manipulate generated PDF then you might want to see PDF SDK as well. Otherwise, for simple operation such as generating PDF, my recommendation is for RDLC.

ELMAH Vs. Log4Net

  ELMAH Log4Net
  Can go complex if you don’t know what are you after Easier to use as compare to Elmah.
  ELMAH will help you to catch any unhandled exception and store them in order to be checked. Log4Net will do what you will ask it to do. Hence you will have to write the code.
  ELMAH can only be used with Web based application. Log4Net can be used with any windows form/ console application. It can also be used with web based application.
  A very good solution for “Screen of Death”: It can just log.
  It can only be used for exception messages I can be used for any kind of logging.
 

 

Practically speaking, we need both.

And that is why it will be great if we can something in between who can pass out the message from one to another.

 

The ELMAH-Appender is what it does. It communicate with the ELMAH library on behalf of Log4Net. So we can use Log4Net like LogManager.GetLogger(typeof(MvcApplication)).Info(“<message>”).

 

For more details please refer: https://nuget.org/packages/elmahappender_log4net/