All posts by KG

REST API Versioning

a) URI Versioning

Add versions in the URI path. Ideally, the URI should represent only the resources. But this is a way of versioning which is used by many clients.

GET /v1/bookings/ HTTP/1.1
Host: example.com
Accept: application/json

Any change to the API’s is followed by a new version, which might break the hyperlinks. But it is easy and is visible so there is no way one can go wrong with this method of versioning.  Foursquare API’s are URI versioned.

e.g. https://api.foursquare.com/v2/venues/40a55d80f964a52020f31ee3/tips

 

Pros:

- Ability to version specific resource branches.
- Semantically dev friendly
- Bookmarking is tightly coupled
- Enables version navigation/discovery

Cons:

- New versions change resource name and location
- Complex proliferation of URI aliases
- Bookmarking is tightly coupled (see pros!)
- Enables version navigation/discovery (see pros!)
- Can't use URI easily to compare identity
- New versions break existing hyperlinks

b) Accept Header Versioning

Provide the versioning as part of the accept-header while passing the request to the server.

One way is

GET /bookings/ HTTP/1.1
Host: example.com
Accept: application/json; version=1.0

Another way is

Accept: application/vnd.myapi.v2 + json with a custom resource type (Oracle has this for their DBaaS services)

They are harder to test and it is hidden so the clients might not know that they have to update it for the next version and miss it entirely. But this is recommended by many as a best practice.

c) Custom Request Header

Not a good option because it could be skipped by the routers while sending the requests because this is not a common request header. So it is not recommended. It is also hidden another problem.

It is usually done by adding a totally new request header like this.

MyAPIVersionRequest-Header: 2

d) Query Parameter Versioning

Add the version as part of the Query Parameters. For e.g. Netflix uses this in their API’s

http://api.netflix.com/catalog/titles/series/70023522?v=1.5

or eBay

http://open.api.ebay.com/shopping?

   callname=FindPopularItems

   &appid=YourAppIDHere

   &version=517

   &siteid=0

   &responseencoding=NV

Again, it is difficult if you want to update to a new version. We need to modify the API calls and also the existing hyperlinks might break (when they finally deprecate the version) and we have to keep parsing the query parameter and re-route the request based on the version. But at least the client knows which version of the API’s needs to be used in their code.

There is no single defined way of versioning of the RESTful API’s. Different services use different types. It depends on how the design is done.

 

References:

http://blog.restcase.com/restful-api-versioning-insights/

http://www.django-rest-framework.org/api-guide/versioning/#versioning-with-rest-framework

 

Securing the RESTful Web Services

Securing the RESTful Web Services

Recap:

Authentication: To ensure the person is who they say they are e.g using an username and password.

Authorization: To ensure that the person has the relevant permissions to do what they are trying to do e.g. accessing/adding resources

Different Authentication Methods:

a) Basic Authentication:

Using HTTP, send in the username and password which is Base64 encoded to the server via a form input. Very basic. Very simple. Very insecure. Anyone can hack this. Better to use the HTTPS instead of HTTP

b) Digest Authentication:

The passwords are encrypted using one of the hashing algorithms and stored. There is no way to get the passwords back. So when the client sends the password during their login session, it is hashed and checked against the one stored. If the client forgets his/her password, a temporary one is created and they are asked to change it.

c) Client Cert Authentication:

The client applies for a certificate to the CA (Certifying Authority). The CA issues the certificate which has the user information along with other credentials (public key). During login, the client sends the certificate. It is validated through the CA to ensure it is a genuine one. HTTPS is used to send the certificate across for secure transmission.

d) API Key Authentication:

Used by Google, FourSpace, Twitter etc when you want to use their RESTful APIs. They provide a Key and a Secret key (mostly called as Client ID and Client Secret). The user details are stored in their database and for every request when the client ID and secret key is passed to them, they authenticate the user across their entries. The client ID and the secret are some random encoded string and are not easy to decode.

 How to do it:

a) web.xml

Use the security-constraint, login-config, security-role etc in the web.xml

e.g.

sec1

b) Security Context

Use javax.ws.rs.core.SecurityContext in the code

The Principal object will have the user information and is used for authentication methods related to BASIC_AUTH, FORM_AUTH, and CLIENT_CERT_AUTH

e.g.

@GET
        @Produces("text/plain;charset=UTF-8")
        @Path("/hello")
        public String sayHello(@Context SecurityContext sc) {
                if (sc.isUserInRole("admin"))  return "Hello World!";
                throw new SecurityException("User is unauthorized.");
        }

c) Annotations

Use the annotations defined in javax.annotations.security packages like @DenyAll, @PermitAll, @DeclareRoles, @RunAs, @DeclareRoles etc

DeclareRoles Declares roles.
DenyAll Specifies that no security roles are allowed to invoke the specified methods.
PermitAll Specifies that all security roles are allowed to invoke the specified methods.
RolesAllowed Specifies the list of security roles that are allowed to invoke the methods in the application.
RunAs Defines the identity of the application during execution in a J2EE container.

e.g.

@Path("/helloworld")
@RolesAllowed({"ADMIN", "ORG1"})
public class helloWorld {

   @GET
   @Path("sayHello")  
   @Produces("text/plain")
   @RolesAllows("ADMIN")
   public String sayHello() {
      return "Hello World!";
   }
}

References:
https://docs.oracle.com/cd/E24329_01/web.1211/e24983/toc.htm
http://howtodoinjava.com/security/restful-web-services-security-guide/

Immutable Classes

What are immutable classes?

Immutable classes are those whose state cannot be changed after construction.

E.g. String is an immutable class in Java and so is Integer. BigDecimal isn’t.

How do we create an immutable class?

a) Make the class final (This means that we cannot extend the class to create a subclass)

b) Do not have a default constructor (That means no one can do a new ClassA() of the class). Instead, like the singleton pattern implementation, have a static method to get the instance of the class or have constructors with inputs in them.

c) Do not allow any methods (accessors i.e setters/getters) which will change the state of the object.

d) Have exclusive access to mutable fields. That means in the getter method which might return the existing field of the object, return a new object.

What are the properties of an immutable class?

a) Automatically thread-safe (no synchronization required) in nature (so all the threading issues are resolved) and cannot be extended.

b) Don’t have to handle clone(). And we can do a lazy initialization of hashCode()

c) have failure atomicity (which means that if this immutable object throws an exception it will not be left in an indeterminate state)

d) Helps in having a stable and fault tolerant system

e) They make for good Map and Set elements as the key elements in these collections should never change while in the collection.

The main issue with immutables: Too many objects lying around. 

Example code (from Marcus Biel’s website):

public final class ImmutableSpaceship {
    private final String name;
    private final Destination destination;
 // Note: There is no default constructor.
    public ImmutableSpaceship(String name) {
        this.name = name;
        this.destination = new Destination("NONE");
    }
    
    private ImmutableSpaceship(String name, Destination destination) {
        this.name = name;
        this.destination = new Destination(destination);
    }
  
    public Destination currentDestination() {
        return new Destination(destination);
    }
    public ImmutableSpaceship newDestination(Destination newDestination) {
        return new ImmutableSpaceship(this.name, newDestination);
    }
[…]
}

References:
https://marcus-biel.com/immutables-in-java/
http://www.javapractices.com/topic/TopicAction.do?Id=29