ServiceStack : une bonne alternative de WCF

Après une étude préalable j'ai abandonné les solutions web services basées sur WCF (RPC et REST) et j'ai choisi ServiceStack en mode REST web services.

Voici les raisons principales.

  1. ServiceStask est vraiment léger, facile à coder et surtout configurer (voir une exemple ci-dessous)
  2. La fonctionnalité est 100% portable entre Windows et Linux alors que ce n'est pas le cas por WCF. Par exemple, WCF ne supporte que "basicHttpBinding" et SOAP 1.1 sous Linux/Mono. Pour moi c'est important, car je développe dans l’environnent hétérogène sous Linux et Windows.
  3. Support plusieurs technologies : RPC/REST, SOAP 1.1/1.2, JSON/XML/CSV etc
  4. Il est facile générer le code depuis le modèle logique
  5. Le même module peut être déploie comme le service autonome (console, service Windows, daemon Linux) aussi que sous IIS/Apache/NGinx etc. pratiquement sans efforts

Programming

Voici une exemple de 2 classes qui implémentent le même service

WCF REST

public class BookmarkService : IHttpHandler
{
   public bool IsReusable 
   { 
   	get { return true;  } 
   }
 
   public void ProcessRequest(HttpContext context)
   {
       Uri uri = context.Request.Url;
       // compare URI to resource templates and find match
       if (Matches(uri, "{username}?tag={tag}"))
       {
           // extract variables from URI
           Dictionary<string, string> vars =
               ExtractVariables(uri, "{username}?tag={tag} ");
           string username = vars["username"];
           string tag = vars["tag"];
           // figure out which HTTP method is being used
           switch (context.Request.HttpMethod)
           {
               // dispatch to internal methods based on URI and HTTP method
               // and write the correct response status & entity body
               case "GET":
                   List<Bookmark> bookmarks = GetBookmarks(username, tag);
                   WriteBookmarksToResponse(context.Response, bookmarks);
                   SetResponseStatus(context.Response, "200", "OK");
                   break;
               case "POST":
  				Bookmark bm = new Bookmark(request.Username, request.Tag);
  				bm.Save();
                   WriteLocationHeader(bm.Id);
                   SetResponseStatus(context.Response, "201", "Created");
                   break;
               default:
                   SetResponseStatus(context.Response, "405", "Method Not Allowed");
           }
       }
       if (Matches(uri, "users/{username}/bookmarks/{id}"))
       {
           // dispatch to internal methods based on URI and HTTP method
           // and write the correct response status & entity body
       }
       // match addition URI templates here
   }
}

ServiceStack REST

public class BookmarkService : RestServiceBase<Bookmark>, IRequiresRequestContext
{
	public override object OnGet(BookmarkRequest request)
	{
		BookmarkResponse response = new BookmarkTypeResponse();
		if (request.Username != null && request.Tag != null)
		{
			BookmarkListResponse responseList = new BookmarkListResponse();
			responseList.BookmarkList = GetBookmarks(request.Username, request.Tag);
			return responseList;
		}
		responce.Status = new ResponseStatus(405, "Method Not Allowed");
		return responce;
	}
 
 
	public override object OnPost(BookmarkRequest request)
	{
		BookmarkResponse response = new BookmarkTypeResponse();
		if (request.Username != null && request.Tag != null)
		{
			Bookmark bm = new Bookmark(request.Username, request.Tag);
			bm.Save();
			response.Bookmark = bm;
			responce.Status = new ResponseStatus(201, "Bookmark saved");
			return response;
		}
		responce.Status = new ResponseStatus(406, "You should specify username and tag");
		return responce;
	}
}

Évidement, le code pour WCF est de plus bas niveau et impose plus de codage mal lisible. L'analyse des strings et comparaisons sont partout.

Il s'agit, donc, de choix "strongly typed DTO" en ServiceStack contre "headers parsing" en WCF.

En plus, quelques points importants

Fichiers *.svc

En mode autonome (hors IIS) WCF a besoin 1 hôte/port par service par défaut (exemples de bricolage à contourner: http://www.blog4work.com/post/2011/06/25...)

SS n'a qu'un seul hôte/port pour l'ensemble de services par défaut

Sous IIS multiples fichiers *.svc sont nécessaires : 1 par classe de service
Pour en éviter l'utilisation et configuration/administration de "URL Rewrite Module" est nécessaire (http://learn.iis.net/page.aspx/460/using...)

ServiceStack n'utilise pas les fichiers *.svc tout à fait.

Configurations

WCF a besoin 1 configuration par services par défaut.

ServiceSstack n'a que une seule configuration pour l'ensemble
(https://github.com/ServiceStack/ServiceS...)

Exploration et débogage dans browser

ServiceStack permet tester et déboguer les services dans browser par défaut (screenshot).

Microsoft.ServiceModel.Web Extensions est nécessaire pour WCF

Conclusions

ServiceStack est plus facile en développement et en déploiement malgré quelques DLL supplémentaires. Il est portable entre Windows et Linux/Mac (Mono) au niveau binaire (pas de compilation). Les tests de performance font une image très positive aussi.

ServiceStack vs WCF