ASP. NET MVC como Servicio REST

Cada vez más en nuestras aplicaciones web necesitamos simplificar nuestros desarrollos y adaptar nuestros recursos a las necesidades del momento. Actualmente la web demanda aplicaciones con interfaces ricas y servicios que retornen la mínima información posible para poder ser consumidas directamente desde el cliente con el mínimo esfuerzo posible.

La Aparición de los servicios REST a facilitado en mucho este tipo de demanda en detrimento de los servicios que utilizan SOAP y WSDL.

Porque no utilizar una aplicación ASP.NET MVC como un servicio REST en vez de los clásicos servicios de WCF si se adapta muchísimo mejor a los principios REST.

Principios REST

  1. Utilizar los métodos HTTP de forma Explícita
  2. Exponer Uris intuitivas
  3. Servicios sin estado “stateLess”
  4. Negociación de contenido

Crearé una aplicación MVC para consumir desde un cliente script utilizando JQuery y AJAX para ver que cumple con todas nuestras necesidades.

1. Métodos HTTP de forma Explícita “CRUD”

GET       –>  Consultas

POST    –>  Inserción

PUT      –>  Actualización

DELETE –> Eliminación

Que mejor que MVC para poder supervisar desde el controlador que petición es demandada dependiendo del método HTTP para realizar la acción correcta.

RESTHttp

Como podéis comprobar podemos filtrar la acción dependiendo del tipo de petición de una manera tan simple como es simplemente decorando la acción con un atributo.

2 Uris intuitivas

Esto es otra característica distintiva de MVC sus rutas orientadas a SEO y fáciles de intuir y con su potentísimo enrutador.

 $.ajax({ url: "/Grupos", type: "GET", dataType: "Json" ... 
 $.ajax({ url: "/Grupos", type: "POST", dataType: "Json"... 

Con la misma ruta obtendremos diferentes resultados dependiendo del tipo de petición HTTP, o si lo preferimos podemos personalizar la ruta para facilitar el aprendizaje de las rutas de los recursos.

HTTP GET –> http://TestMVCREST/Grupos

HTTP POST –> http://TestMVCREST/Add/Grupo

3 Servicio sin Estado

Como el propio protocolo HTTP cada llamada será independiente y no se mantendrá el estado dejando esa responsabilidad al cliente que realiza las llamadas.

4 Negociación de Contenido

Por último, es bueno construir los servicios de manera que usen el atributo HTTP Accept del encabezado, en donde el valor de este campo es el tipo MIME. De esta manera los clientes pueden elegir que formato de datos quieren leer y minimiza el acoplamiento de datos entre el servicio y las aplicaciones que lo consumen.

Algunos de los tipos MIME más usados para los servicios web REST son:

MIME-Type

Content-Type

JSON

application/json

XML

application/xml

XHTML

application/xhtml+xml

Esto permite que el servicio sea utilizado por distintos clientes escritos en diferentes lenguajes, corriendo en diversas plataformas y dispositivos.  Para eso he creado un cliente que consumirá el servicio MVC REST desde una página HTML con Jquery y llamadas AJAX.

HTTP GET

Para recuperar los datos de los grupos de usuarios:

Utilizamos la misma llamada AJAX para recuperar los datos, pero especificando en que formato los queremos Json o XML en el parámetro “contentType”.

Cliente AJAX:

function GetGruposJSon() {

  $.ajax({ url: "/Grupos", type: "GET", dataType:"Json", contentType: "application/json",
     success: GetGruposOk, error: GetGruposKO
  });
}
function GetGruposXML() {

  $.ajax({ url: "/Grupos", type: "GET", contentType: "application/xml", dataType: "xml",
    success: GetGruposOk, error: GetGruposKO
  });
}

Servicio REST que devuelve la lista de grupos.

No me entretendré en explicar como devolver el formato dependiendo del contentType, porque Eduard Tomas ya lo explicó perfectamente es esta entrada ASP.NET MVC – Formato de salida según Content-Type

REST1

 

REST21

Los datos en el cliente en formato JSon:

RESTJson

Los datos en el cliente en formato XML:

RESTXML

HTTP POST

Para insertar un nuevo grupo a la lista:

function AddGrupo() {

  var nuevoGrupo = { nombre: "LoNetCamp", origen: "Tarragona", imagen: "" };

  $.ajax({ url: "/Grupos", type: "POST", dataType: "Json", processData: true,
     success: AddGrupoOk, error: AddGrupoKo, data: nuevoGrupo
  });
}

Añadimos los datos como un objeto para que se envíen en el formulario como datos y no en el QueryString, la petición es en la misma ruta pero diferente tipo de petición.

RESTPost

 

Desde nuestro cliente HTML obtendremos acceso a los recursos del servicio MVC REST sin problemas.

RESTOK

Esta práctica es muy útil para consumir los servicios desde clientes web de una forma ligera y con llamadas AJAX, pero hay que tener en cuenta sus limitaciones de seguridad y no es una solución que podamos utilizar para todos nuestros escenarios.

10 comentarios en “ASP. NET MVC como Servicio REST”

  1. Hola,

    ¿Ves mejor la opción de MVC que usar WCF Data Services o WCF Ria Services (un DomainServices)? En estas dos opciones el hecho de publicar por REST u OData se simplifica bastante..

    El resultado final sería el mismo, no?

    Un saludo,

  2. Hola Marc:

    Yo creo que cada aunque se pueda hacer un servicio REST con ASP.NET MVC, no es mejor opción que usar WCF, puesto que WCF presenta una arquitectura más sólida para desarollar servicios RESTful (Algo que no has comentado en tu post y que es bastante importante) y te aseguro que se adapta mucho mejor que ASP.NET MVC (Que creo su finalidad no es esta). A parte en WCF 4.0 se han añadido nuevas caracteristicas muy interesantes para REST.

    Un saludo

  3. MMmmm… No conozco suficiente WCF así que solo puedo hablar desde la ignorancia, como un telepredicador cualquiera :p

    @Luis
    Lo que si puedo decir es que es realmente fácil usar ASP.NET MVC para servicios REST, sin tener que liarse con ficheros de configuración, bindings, etc.
    Como de fácil es con WCF publicar endpoints en IIS que no terminen con el .svc? Y gestionar los verbos http? Eso es trivial en ASP.NET MVC.
    Yo ahora mismo, no veo ningún motivo para usar WCF para publicar servicios REST (aunque insisto: puede ser por falta de conocimiento).

    @Ibon
    Tu conoces bastante bien WCF, tengo entendido no? Podrías hacer un post similar al de Marc (si no lo has hecho ya :p) y así los que sólo conocemos la visión MVC para realizar servicios REST podremos “comparar”.

    @Marc
    Muy buen post, tenía uno similar en mente… lo tacho de mis tareas pendientes!! Así me gusta que estés dejando de lado webforms y pasándote al “lado oscuro de asp.net” :p :p :p

    Un saludo!

  4. Buenaas,

    Marc, gran post.

    Desde mi punto de vista, está claro que currarse con MVC un acceso tipo REST a una fuente de datos completa no tendría mucho sentido estando ahí los WCF Data Services y OData.

    Sin embargo, para escenarios más simples como el que plantea Marc, no me parece una mala opción, todo lo contrario. Si estamos desarrollando una aplicación web con MVC cuyas vistas van a ser las principales consumidoras de los servicios vía Ajax, es muy sencillo y cómodo utilizar esta técnica para ello, pues integramos las rutas, controladores y acciones dentro del mismo proyecto de forma muy natural… y no tiene ninguna contraindicación (creo ;-))

    Nos vemos!

  5. @Luis
    WCF se le puede poner muchas etiquetas pero no la de RESTFul , para ser RESTFul WCF tendría que seguir al 100% con los principios REST y no es así. WCF está basado en un sistema RPC y todo lo que se ha hecho es maquillar su utilización para que se adapte en algunos principios REST pero no al 100%.
    Por ejemplo si utilizas el atributo WEBGet para utilizar el servicio con la filosofía REST te limita a tener solo un formato de datos para esa llamada “RequestFormat, ResponseFormat” no podemos utilizar el negociador de contenido.

    @Ibon @Luis
    Como bien dice @José este es un escenario muy concreto y como he puesto al final de la entrada no se puede utilizar en todo momento, pero creo que para este escenario es mucho más ágil y sencillo utilizar el patrón MVC que ir publicando servicios para consumirlos desde clientes script.

    Realmente creo que es una implementacion de REST mucho mas natural.

    Pero estoy abierto a que me convenzáis de lo contrario 😉

  6. Hola,

    No se puede decir nada, que pronto le dais trabajo a uno.

    Yo estoy en lo que dices, hay varias tecnologías que podría llegar a emplearse, pero también muchos depende. El escenario y las restricciones que pone el cliente muchas veces delimita la opción elegida.

    Aunque me apunto que podría estar bien un tema al respecto, os pongo algún enlace que podría venir bien para aclarar el funcionamiento de WCF Data Services y WCF RIA Services.

    Escribí una serie sobre WCF RIA Services.
    Con esta tecnología es muy fácil escribir un servicio por OData y exponer operaciones CRUD. Se integra a la perfección con un EF.
    http://geeks.ms/blogs/ilanda/archive/2009/12/31/wcf-ria-services-resumen.aspx
    Tb simplifica bastante la vida al hacer aplicaciones con Silverlight de tipo línea de negocio.

    Sobre DataServices escribí algo hace tiempo, con las primeras versiones.
    http://geeks.ms/blogs/ilanda/archive/2008/05/15/ado-net-data-services-ideas-claves.aspx

    Lo dicho, hay un fin de dependes…

    Por cierto, el post muy bueno, sabía que se podía hacer pero no lo había visto nunca…no soy muy pro-mvc 🙂

  7. @Luis
    Como el mismo dice en el libro “Services that follow this styles are know as RESTFUL. Note that these architectural constraint are more what you’d “guidelines” than actual rules. Some services will use all these constraints, and some will use only some of the constraints.”

    WCF no sigue todas las normas de REST y yo soy uno de esos que cree que aunque se puedan autodenominarse RESTFUL a muchas librerías que están en el mercado, solo es RESTFUL aquellas que siguen al 100% todas las reglas REST y la gran mayoría no las son.

    Con esto no quiero decir que con WCF no se pueda utilizar REST “que si se puede”, pero autodenominarse RESTFUL son palabras mayores. 😉

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *