REST con ASP.NET Web API

Una de las novedades que más entusiasmaron de la versión beta de ASP.NET MVC 4  son los templates de proyectos ASP.NET Web API. Estos nuevos “tipos” de proyectos nos permiten crear, de una manera muy simple, aplicaciones cuyo propósito es exponer servicios bajo el protocolo HTTP utilizando el estilo de arquitectura REST  (Representational State Transfer).

Antes de continuar con Web API, veamos de que se trata REST.

REST (Representational State Transfer) es un estilo de arquitectura de software para sistemas hipermedias distribuidos tales como la Web. El término fue introducido en la tesis doctoral de Roy Fielding  en el año 2000, quien es uno de los principales autores de la especificación de HTTP.

Los servicios web basados en REST intentan trabajar de manera similar al protocolo HTTP, ya que la interfaz de los mismos será establecida a partir de un conjunto conocido de operaciones estándar (por ejemplo GET, POST, PUT,…). De esta forma, nos abstraernos de los protocolos basados en patrones de intercambio de mensajes, como los utilizados en los servicios web basados en SOA (de seguro estará pensando en el viejo y conocido protocolo de servicios web SOAP).

Es importante que quede claro que REST no es un estándar, sino un estilo de arquitectura que se basa en ciertos estándares, como HTTP, URL, XML, JSON y MIME entre otros.

Volviendo a Web API, algunas de las características  de este framework son:

  • Integración con el mecanismo de routing.
  • Negociación de contenidos (cliente y servidor pueden negocias el formato del intercambio de información).
  • Soporte de Model Bindings, Validations y Actions Filters.
  • Soporte de consultas con OData.
  • Hosting autocontenido (podes publicar nuestra API en IIS o directamente con un ejecutable).

Que mejor forma de explicar todo lo que estuvimos viendo que un ejemplo ;). Para eso vamos a crear un nuevo proyecto ASP.NET MVC 4 al que llamaremos MvcWebApi. Pero ojo, para trabajar Web API debemos seleccionar, dentro de las templates del framework, la nueva plantilla de proyectos “Web Api”:

Template de proyecto Web API

Template de proyecto Web API

Podemos observar que la estructura del proyecto es similar a la de una aplicación web ASP.NET MVCtradicional” (por ejemplo los directorios utilizados por convención del framework siguen existiendo: Models, Views y Controllers como así también los archivos de configuración).

Estructura de un proyecto ASP.NET Web API

Estructura de un proyecto ASP.NET Web API

Analicemos el controlador que Visual Studio nos genera por defecto:

Definición de ValuesController

Definición de ValuesController

El primer “gran cambio” con el cual nos vamos a encontrar es que los controladores ya no heredan de Controller sino que lo hacen de ApiController. Este nuevo tipo de controlador me permite que los métodos  de acción no retornen “vistas” (ActionResult) sino que, por el contrario, devuelvan los datos propiamente dichos (el formato en que viajaran los datos, Json o XML por ejemplo, se negociara entre el cliente y el servidor). Por último, Web API trabaja por convención en lo que respecta a los nombres de los métodos de acción y los verbos HTTP, por lo tanto no es necesario decorar un método con el atributo [HttpPost] para establecer que es un método POST. Lo que tenemos que hacer es simplemente llamar al método de acción Post() (también podemos modificar el nombre del método,  siempre que el mismo termine con el nombre del verbo HTTP, como por ejemplo: ClientPost()).

Detengamonos un momento en este último punto, y retornemos a REST. Un aspecto muy importante de este estilo de arquitectura es que trabaja con recursos. Esto que quiere decir?… que cada servicio que invoquemos, intentará realizar una operación, de un conjunto conocido de operaciones, sobre un recurso o una serie de recursos (cada uno de estos recursos serán identificados mediante URIs como veremos más adelante).

Dicho esto, se podrán imaginar que existe cierta similitud entre los tipos de petición HTTP y las operaciones que podemos realizar sobre los recursos con nuestro servicio. Una aproximación podría ser la siguiente:

HTTP OPERACIÓN ACCIÓN
POST CREATE Crear un nuevo recurso
GET RETRIEVE Obtener la representación de un recurso
PUT UPDATE Actualizar un recurso
DELETE DELETE Eliminar un recurso

Sabiendo esto, vamos a definir las operaciones de nuestro servicio (que por el momento trabajara con el recurso “Cliente”):

RECURSO MÉTODO
Cliente GET Obtener la representación de un cliente
Todos los clientes GET Obtener la representación de una la lista de clientes
Cliente POST Crear un cliente
Cliente PUT Actualizar un cliente
Cliente DELETE Eliminar un cliente

Volvamos al proyecto para definir el modelo que representará al recursoCliente”. Para eso vamos a agregar la clase Cliente dentro de la carpeta “Models” > click derecho sobre Models > Add > Class > Cliente.cs:

Definición del modelo Cliente

Definición del modelo Cliente

Ahora es el momento de trabajar sobre el controlador. Para eso vamos a crear un nuevo controller  llamado ClientesController haciendo click derecho sobre el directorio Controllers > Add > Controller… y una vez que se nos despligue la ventana “Add Controller” seleccionaremos dentro de los templates disponible la opción “Empty API Controller”:

Creando nuestro API Controller

Creando nuestro API Controller

Escribamos las acciones (operaciones) usando como en base lo que definimos en la tabla anterior:

Definición de ClientesController

Definición de ClientesController

Si ejecutamos el proyecto e intentamos recuperar un cliente utilizando nuestro servicio REST, nos encontraremos con que no se encuentra el recurso solicitado :(:

Error al acceder a nuestro servicio

Error al acceder a nuestro servicio

Por qué ocurrió esto? Si inspeccionamos las entradas en el mecanismo de routing de ASP.NET MVC (dentro de Global.asax), nos vamos a encontrar con una “nueva” entrada llamada DefaultApi que será utilizada por nuestra Web API REST. Como observación, van a notar que la misma es registrada por el método MapHttpRoute, a diferencia de los mapeos tradicionales de ASP.NET MVC que son realizados con el método MapRoute.

DefaultApi

DefaultApi

Conclusión, cuando llamemos a las URL de nuestros servicios REST, vamos hacerlo anteponiendo “api” en la URL. Por ejemplo, para recuperar la lista de clientes debemos acceder de la siguiente manera:

http://localhost:49171/Api/Clientes

Pasemos de la teoría a la práctica 🙂

Nuestro servicio REST en marcha!

Nuestro servicio REST en marcha!

En este caso la negociación entre cliente-servidor definió que el contenido devuelto sea en formato XML, sin embargo esto no debe ser necesariamente así (veremos en otros post como definir el formato que más cómodo-útil nos resulte).

Habrán notado también es que no fue necesario especificar el nombré de la acción en la URL (es más, si prestan atención a la regla DefaultApi del enrutador, la acción no es tenida en cuenta). Para saber qué método se debe invocar ante cada petición, lo que hace el framework es trabajar por convención, esto quiere decir que ante cada request, se accederá al método de acción llamado de la misma forma que el verbo HTTP que lo invoca,  teniendo en cuenta también los parámetros enviados.

Veamos como quedaría la tabla teniendo en cuanta las operaciones a realizar sobre nuestro recurso:

RECURSO MÉTODO
Cliente GET http://localhost:49171/Api/Clientes/5
Todos los clientes GET http://localhost:49171/Api/Clientes/5/sebis
Cliente POST http://localhost:49171/Api/Clientes/5
Cliente PUT http://localhost:49171/Api/Clientes
Cliente DELETE http://localhost:49171/Api/Clientes/5/sebis

Otra cosa interesante, es que a diferencia de las aplicaciones web ASP.NET MVC, podemos definir más de un método con el mismo nombre. Por ejemplo podemos tener los métodos Get(), Get(int id) y Get(int id, string name). Para este último caso, simplemente debemos agregar un nuevo mapeo HTTP en el mecanismo de routing:

Definiendo nuestra entrada personalizada

Definiendo nuestra entrada personalizada

El procesador se encargará de acceder al método correspondiente a partir del tipo de petición realizada (GET, POST, PUT…) y de los parámetros enviados.

A esta altura muchos se preguntarán por qué usar servicios basados en REST con Web API si ya disponemos en .NET de otras tecnologías o frameworks para trabajar con web services (ASMX, WSE, WCF,… , WCF Web Api)?  Una respuesta es que ASP.NET Web Api integra de una manera muy sencilla lo mejor de WCF Web API y ASP.NET MVC – excelente noticia quienes desarrollamos con ASP.NET MVC :). Otra buena respuesta a esta pregunta es que REST esta construido sobre los pilares de la web, y esta por demás decir la misma ha sido muy exitosa. Recuerdo un artículo donde decía que “la Web ha sido la única aplicación distribuida que ha conseguido ser escalable al tamaño de Internet” y debido a que REST se basa en ella, podemos decir con seguridad que estamos tomando el camino correcto.

Espero que les haya sido de utilidad, y en próximos post vamos a ver la forma de utilizar los servicios por medio de jQuery y otras características de Web API.

Puedes encontrar este articulo en MSExpertos.

Anuncios