Sunday, April 6, 2014

Introducción a ServiceStack

ServiceStack es un framework opensource que se presenta como alternativa a WCF para la creación de Web Services .Net sobre HTTP. Al haber sido desarrollado en años recientes (tiene alrededor de 4 años en el mercado), provee una forma rápida y limpia de desarrollar servicios web orientados a la utlización de POCOS (Plain Old CRL Objects).

Ventajas:
  • Simplicidad
  • Velocidad
  • Uso de las mejores prácticas
  • Orientado a modelos
  • Sin conocimiento de los endpoints, se envía un objecto C#, se recibe un objeto C#.
  • No utiliza configuraciones en XML, no utiliza código autogenerado, utiliza convenciones.
  • Disponible para .NET y para MONO (compatibilidad con sistemas Linux)
  • Servicios altamente testeables, pues están totalmente desacoplados de HTTP
Diferentes Endpoints

Ya que diferentes endpoints tienen diferentes ventajas según el contexto. ServiceStack soporta los siguientes endpoints de forma inicial:
  •  XML ( + urls GET REST)
  • JSON (+ urls GET REST)
  • JSV (+urls GET REST): Json-like separeted values, es un formato inspirado en JSON que usa un estilo CSV para una mejor performance.
  • SOAP 1.1/1.2
Creación de un Servicio Básico




Abriremos Visual Studio y crearemos un proyecto Web vacío nuevo.



Mediante NuGet, instalaremos ServiceStack



Una vez instalado, debemos editar nuestro Web.config para que luzca de la siguiente forma:

<?xml version="1.0"?>

<configuration>
  <system.web>
    <httpHandlers>
      <add path="*" type="ServiceStack.HttpHandlerFactory, ServiceStack" verb="*"/>
    </httpHandlers>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <!-- Required for IIS 7.0 (and above?) -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <add path="*" name="ServiceStack.Factory" type="ServiceStack.HttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
    </handlers>
  </system.webServer>
</configuration>

Añadiremos la clase Global.asax a nuestro proyecto web. Para ello haremos click derecho sobre el proyecto y luego "add new item..."



Cada servicio en ServiceStack está formado por tres partes:
  • Un DTO de request
  • La implementación del servicio
  • Un DTO de respuesta
Añadiremos entonces un servicio llamado "Saludo" para el cual primero crearemos su request:

namespace ServiceStack.Web
{
    [Route("/saludo")]
    [Route("/saludo/{Nombre}")]
    public class Saludo
    {
        public string Nombre { get; set; }
    }
}

En esta primera clase, es importante notar el uso de atributo Route, por el cual estamos definiendo las URLs REST que utilizará el mismo.

Luego crearemos su objeto response:

namespace ServiceStack.Web
{
    public class SaludoResponse
    {
        public string Respuesta { get; set; }
    }
}

Aquí, es importante utilizar la convención de nombres. La respuesta del request inicial siempre deberá llamarse como dicho request + "Response". Además, es importante que tanto el request como el response en encuentren dentro de un mismo namespace, para que ServiceStack los reconozca como un par.

Por último crearemos la implementación del servicio, esta clase deberá implementar la interfaz IService. Crearemos un método llamado "Any", este recibirá un objeto SaludoRequest y devolverá un objeto SaludoResponse. 

namespace ServiceStack.Web
{
    public class SaludoService : IService
    {
        public object Any(Saludo request)
        {
            return new SaludoResponse() { Respuesta = "Hola " +
request.Nombre + "! Cómo te va?" };
        }
    }
}

Al utilizar "Any" como nombre de método, estamos indicando que este método se encarga de gestionar cualquier tipo de llamada HTTP (Get, Post, Put, Delete). Si queremos utilizar la convención de nombres para cada tipo de llamada HTTP, entonces podemos crear métodos acordes llamados Get, Post, Put y Delete.

Ahora registraremos el servicio en el global.asax de la siguiente forma

namespace ServiceStack.Web
{
    public class Global : System.Web.HttpApplication
    {
        public class AppHost : AppHostBase
        {
            //Informamos a Service Stack el nombre de la aplicación
// y dónde encontrar los web services
public AppHost() : base("Saludo web service", typeof(SaludoService).Assembly) { }

            public override void Configure(Funq.Container container)
            {
                // aquí podemos registrar dependencias
            }
        }

        // Inicializar la aplicación
        protected void Application_Start(object sender, EventArgs e)
        {
            new AppHost().Init();
        }
    }
}


Y eso es todo ! Si levantamos la aplicación, veremos lo siguiente:


Como vemos, se listan las operaciones disponibles por el servicio y tendremos acceso a la forma en que podemos acceder al mismo mediante llamadas utilizando REST o SOAP. Por ejemplo, si hacemos click en Saludo JSON...


Y si hacemos click en Saludo para SOAP 1.2 ...


Podemos probar el servicio haciendo una llamada HTTP GET mediante el navegador, y entonces nos encontraremos lo siguiente:

 Podemos visualizar el resultado en XML ...


O en JSON...

Hasta aquí, en muy pocos pasos, contamos ya con un servicio http operativo. En la siguiente entrada, haré una pequeña refactorización del código y crearemos un cliente C# para la comunicación directa con el servicio como si se tratara de una librería más.

No comments:

Post a Comment