Monday, August 28, 2017

RESTful Services - Dealing with REST vs WCF




Hi folks -

With the advent of the new changes around the Common Data Service (CDS), there are new concepts to be learned as Microsoft Dynamics AX Architects/Developers. If you would like to learn more about this, please go to https://powerapps.microsoft.com/en-us/guided-learning/learning-common-data-service/

The purpose of this post is to provide a simple basic understanding of what REST is, its rules, and a simple example on how it differs from WCF, which has been the main service layer in Dynamics AX  2012.

Moving on, in recent years, it has become clear that HTTP is not just for serving up HTML/HTML5 pages. It is also a powerful platform for building Web APIs (D365 for Ops is a good example) using a handful of verbs (GET, POST, and so forth) plus a few simple concepts such as URIs and headers.

Additionally there are six guiding constraints that define a RESTful system, these constraints restrict the ways that the server may process and respond to client requests so that, by operating within these constraints, the service gains desirable non-functional properties, such as performance, scalability, simplicity, modifiability, visibility, portability, and reliability. If a service violates any of the required constraints, it cannot be considered RESTful.

REST constraints

Client-server architecture

The first constraints added to the hybrid style are those of the client-server architectural style. The principle behind the client-server constraints is the separation of concerns. Separating the user interface concerns from the data storage concerns improves the portability of the user interface across multiple platforms. It also improves scalability by simplifying the server components.

Stateless protocol

The client–server communication is constrained by no client context being stored on the server between requests. Each request from any client contains all the information necessary to service the request, and session state is held in the client. The session state can be transferred by the server to another service such as a database to maintain a persistent state for a period and allow authentication. The client begins sending requests when it is ready to make the transition to a new state. While one or more requests are outstanding, the client is considered to be in transition. The representation of each application state contains links that may be used the next time the client chooses to initiate a new state-transition.

Cacheability

Clients and intermediaries can cache responses. Responses must therefore, implicitly or explicitly, define themselves as cacheable or not to prevent clients from reusing stale or inappropriate data in response to further requests. Well-managed caching partially or completely eliminates some client–server interactions, further improving scalability and performance.

Layered system

A client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way. Intermediary servers may improve system scalability by enabling load balancing and by providing shared caches. They may also enforce security policies.

Code on demand

Servers can temporarily extend or customize the functionality of a client by transferring executable code. Examples of this may include compiled components such as  client-side scripts such as JavaScript.

Uniform interface

The uniform interface constraint is fundamental to the design of any REST service. It simplifies and decouples the architecture, which enables each part to evolve independently. The four constraints for this uniform interface are:

Resource identification in requests

Individual resources are identified in requests, for example using URIs in Web-based REST systems. The resources themselves are conceptually separate from the representations that are returned to the client. For example, the server may send data from its database as HTML, XML or JSON, none of which are the server's internal representation. A good example of this can be seeing in power apps when creating JSON mappings.

The above is important to understand as when creating RESTful services to interact with our power apps or flow, these constraints will help us to create a true MVC pattern (using MS tools) so we can take advantage of scalability, reusability, and smart data management. Let's look at a simple comparison between WCF and REST.  

Services - WCF/REST

Unlike WCF where a service is an address to a physical file (i.e. an address that maps directly to a service class or .svc file), Service addresses with MVC are REST-style routes that map to controller methods - they fit nicely with REST-API Specs.

Let's look at an example of a Task Management routine with WCF:

[Service Contract]

public interface ITaskService
{
[Operation Contract]

Task GetTask(long Task ID);
}

public class TaskService : ITaskService
{

private readolny IRepository _repository;

Public TaskService(IRepository repository)

{
_repository = repository;
}

Public Task GetTask(long taskId)

{
        Return _repository.Get<Task>(taskId);
}
}

The resulting service for the above WCF service will look like this: http://MyServer?TaskService.svc

The below code achieves the same result than the above one. The only difference is that is built with MVC4 and it also is JavaScript friendly (JavaScript meaning for any web based app). The main difference is that the below code would involve creating a controller instead of a service class. Further, the method that takes care of retrieving the TaskId exist in the controller itself, unlike WCF where it would be defined by a contract.

Public class TaskController : Controller
{

private readolny IRepository _repository;

Public TaskController(IRepository repository)
{
_repository = repository;
}

Public ActionResult Get(long taskId)
{
Return JSON(_repository.Get<Task>(taskId));
}
}

In order to retrieve a single task - the MVC4 will not need SOAP, or any service class to contract with along with an operation. The call will look like this (assuming there is an appropriately  configured route.



 
Let's move further, and look an example with the ApiController. The URL will look different as the above example contains the Get in the URL. The ApiController base class was built to enable RESTful services, and by using it we would only need to return the object(s) in a collection and the data related to that collection.

Public class TaskController : ApiController
{
private readolny IRepository _repository;
Public TaskController(IRepository repository)
{
_repository = repository;
}

Public Task Get(long taskId)
{
Return repository.Get<Task>(taskId));
}
}


The URL will look like this http://MyServer/Task/001


If we note, in the address above we don't include the method name (i.e. Get) like we did in the example where we were using the Controller base class instead of the ApiController one. The amazing reason for this is because when using the ApiController base class, it automatically maps to the corresponding controller methods, therefore it helps us to create API the flows more naturally with the REST architecture.
 
Thanks all for now!