SignalR – Introducción

SignalRHace tiempo que tengo intenciones de comenzar a escribir sobre este tema, pero por una cosa u otra lo fui postergando. Para quienes no lo conozcan, SignalR es un framework de la pila de tecnologías web de Microsoft pensado para la construcción de aplicaciones en tiempo real. Las aplicaciones web con funcionalidad en tiempo real son aquellas que tienen la capacidad de enviar – desde el servidor – notificaciones al instante a los clientes conectados, en lugar de esperar que ellos vuelvan a solicitarlos ya sea por medio de polling o requests.

Ejemplos de este tipo de aplicaciones son los juegos “online” multi-usuarios, herramientas colaborativas como por ejemplo Google Docs u Office Web Apps, servicios de notificaciones en vivo, chats y otros tipos de servicios que actualmente son muy comunes de ver en aplicaciones como Facebook y Twiter.

La definición para SignalR que nos da el sitio oficial es la siguiente:

ASP.NET SignalR is a new library for ASP.NET developers that makes it incredibly simple to add real-time web functionality to your applications. What is “real-time web” functionality? It’s the ability to have your server-side code push content to the connected clients as it happens, in real-time.

SignalR es el marco de trabajo perfecto para el desarrollo de aplicaciones en Internet que soporten múltiples usuarios colaborando al mismo tiempo.  Y para que esto sea posible nos provee de una API que abstrae al desarrollador de las cuestiones de bajo nivel y nos brinda componentes para ambos extremos de la comunicación – cliente y servidor – tema que ya veremos más adelante.

Es importante saber que es una librería que se monta sobre el stack de tecnologías para la web ASP.NET y se encuentra al mismo nivel de otros frameworks bien conocidos por nosotros como Web API o MVC:

SignalR

SignalR

Como bien lo muestra el gráfico tanto SignalR como Web API están pensados para resolver implementaciones orientadas a servicios mientras que Web Forms y MVC fueron diseñados para la construcción de aplicaciones web.

Siguiendo la movida que implementó Microsoft en los últimos años, SignalR es open source – licencia Apache 2.0 – lo que nos permite estudiar sus fuentes y colaborar a través de GitHub. La versión 1.0 salio en Febrero de 2013 y la versión 2.0 unos meses más tarde en Octubre del mismo año. Al momento de escribir esto se encuentra en la versión 2.2.0 que se lanzo en Enero de este año y es la que utilizaremos en los próximos post.

Para finalizar con esta pequeña introducción contarles que SignalR está siendo utilizado en muchos proyectos reales como ser Web Apps de Office, SkyDrive y Office 365 entre otras, lo que habla de un marco de trabajo estable. Otro ejemplo es el juego Shootr construido en su totalidad con esta tecnología.

En las próximas entregas vamos a contar algunas de las características que hacen de este framework una opción perfecta para la creación de aplicaciones multi-usuarios en tiempo real de una manera realmente sencilla para los desarrolladores.

¡Nos vemos!

One ASP.NET

Para quienes llevan un buen tiempo programando con tecnologías .NET recordaran que aya por el 2001 Microsoft sacaba al mercado algo llamado .NET Framework y acto seguido una nueva tecnología llamada ASP.NET. En aquellos años Internet empezaba a jugar un papel cada vez mas importante y era el momento de entrar en ese mercado. Y ASP.NET fue pensado justamente para atraer a los desarrolladores de aplicaciones de escritorio al desarrollo de páginas-aplicaciones web. Para que el cambio fuese lo mas transparente posible para los developers, ASP.NET adoptó el concepto de WebForms: formularios web donde podíamos arrastrar controles y con un simple “doble click” bindear eventos a los mismos y programarlos en el code behind (una forma de desarrollo muy parecida a la de WinForms).

Luego de un largo tiempo, a principios de 2009, aparece dentro de ASP.NET el patrón MVC y con él ASP.NET MVC 1 (una gran alegría para muchos de los desarrolladores web que esperábamos un cambio en el framework para que sea más orientado a la web!).  A medida que avanzaron los años este framework fue creciendo y con el aparecieron las versiones 2, 3, 4 y recientemente la versión 5.

Pero ASP.NET no solo se conforma de estos dos frameworks (Web Forms y MVC), con los grandes avances en el mundo web, en 2012 se añaden nuevos frameworks a la familia: Web API, SPA y SignalR (tengo pendiente un post sobre el mismo).

Ahora bien, aunque todos forman parte de la familia ASP.NET, generalmente se los suele identificar como proyectos independiente entre sí, sin relación uno con el otro. Esta visión no es correcta y con One ASP.NET se quiere reforzar esta idea.

La idea tras One ASP.NET es tener un único proyecto ASP.NET que podemos customizarlo a partir un conjunto de tecnologías web:

One ASPNET

One ASPNET

Por eso con Visual Studio 2013 cuando vamos a crear un nuevo proyecto web nos vamos a encontrar con una única plantilla “ASP.NET Web Application“:

ASP.NET Web Application

ASP.NET Web Application

Este cambio claramente refuerza el concepto de una única aplicación ASP.NET.

Una vez que creamos el proyecto se nos pedirá que elijamos las tecnologías con las que vamos a trabajar:

Seleccionando las tecnologías ASP.NET con las cuales trabajar.

Seleccionando las tecnologías ASP.NET con las cuales trabajar.

También podemos configurar de forma unificada aspectos como autenticación y testing unitario.

Algunos podrán decir que esto es simplemente un paso “extra” en la selección del template de proyecto a utilizar, sin embargo tras esta idea hay una nueva visión que pretende integrar este conjuntos de tecnologías bajo una única plataforma y finalmente borrar ese concepto que tenemos de proyectos independientes e incompatibles entre sí.

Por último recomiendo el post de José Manuel Alarcon hablando al respecto!

Abrazos!

Routing en WebAPI [quickly post]

Hace unos días, un colega me comentó acerca de un problema que tenía con el mecanismo de routing de WebAPI en un proyecto ASP.NET MVC 4. Me comento que se había basado en el primer post que escribí de la serie Web API, en el cual había utilizado un proyecto ASP.NET MVC 3.

Revisando el código generado en ambos proyecto, descubrí que dicho mecanismo había cambiado de una versión a la otra (sobre todo la ubicación en donde se definen las reglas de ruteo).

En proyectos ASP.NET MVC 4 la definición de dichas reglas esta a cargo de la clase WebApiConfig:

WebApiConfig

WebApiConfig

 Esta clase posee el método Register(HttpConfiguration config) el cual es utilizado para definir las reglas de routing que son especificas de Web API:

Agregando una nueva regla de ruteo.

Agregando una nueva regla de ruteo.

Por lo tanto, si necesito generar una nueva regla para los servicios expuestos con Web API, el lugar indicado es este. Hagamos un ejemplo sencillo para que quede claro. Vamos a agregar una nueva entrada llamada “NameApi” que permite al usuario utilizar URIs con el siguiente formato:

http://localhost:301283/api/values/1/sebis

Hecho esto, vayamos al controlador ValuesController (el cual hereda de ApiController) y  agreguemos un nuevo método GET (el hace provecho de esta nueva regla):

Get Method

Get Method

Ahora ejecutemos e invoquemos la URI (escrita unas líneas mas arriba) para corroborar que el servicio nos retorna el valor correcto:

Resultado obtenido del servicio

Resultado obtenido del servicio

Espero que les sea de utilidad.

Implementando características de OData con ASP.NET WebAPI

En esta nueva entrega sobre ASP.NET Web API vamos a hablar sobre las características que este soporta del protocolo Open Data Protocol (de ahora en mas OData).

Open Data Protocol

Open Data Protocol

Antes de comenzar, vamos a realizar una pequeñísima introducción a Open Data Protocol.

OData es un protocolo abierto – open protocol – creado por Microsoft para exponer datos como servicio. Este se basa en estándares conocidos de Internet como HTTP, Atom (AtomPub) y JSON. Como todo protocolo de servicios, uno de los fines principales es poder independizar los datos de la aplicación o sitio web que los utiliza. Los clientes que consumen servicios a través el protocolo OData pueden hacerlo bajo formatos como Atom, JSON o XML plano, pero además incluyendo características como paginación, ordenación y filtrosquerys -.

Otra característica interesante de OData es que nos permite exponer y acceder a información de una gran variedad de fuentes, incluyendo, bases de datos relacionales, sistemas de archivos, sistemas de gestión de contenidos y sitios web tradicionales.

Escenarios de despliegue de OData

Escenarios de despliegue de OData

Ahora bien, de todas las características que ofrece OData, la que nos interesa en este momento es la utilización de convenciones URI que nos permitirán, entre otras cosas, realizar operaciones como navegación, filtrado, orden y paginación de datos en la solicitud de un recurso.

URI Components

URI Components

La utilización de estas convenciones nos permiten, desde la misma URI del recurso, especificar query options que serán aplicadas al momento de obtener un recurso. Podemos ver en el gráfico anterior – URI Components – que las opciones de consultas se especifican al final de la URI.

Ejemplos de query options son:

  • $filter : permite aplicar filtros sobre el resultado.
  • $orderby : permite ordenar por alguna condición el resultado
  • $top : permite recuperar un cierto número de resultados.
  • $skip : permite saltear un cierto número de resultados.

Vayamos a un ejemplo, si quisiera obtener la lista de clientes ordenadas por nombre, debería invocar al servicio utilizando la siguiente URI:

http://localhost:[port]/api/clientes?$orderby=Nombre

Ahora bien, ASP.NET Web API trae soporte para un subconjunto de características del protocolo OData. Una de ellas es que podemos trabajar con las convenciones URI que trabajaran en la interacción con los controladores de nuestra API.

Para trabajar con ellas simplemente debemos modificar el tipo de datos de la respuesta de nuestro método. Recordaran que en post anteriores el método retornaba un objeto IEnumerable:

Método de acción Get() retornando un IEnumerable

Método de acción Get() retornando un IEnumerable

En este caso debemos vamos a modificar la firma y el cuerpo del método para que retorne un objeto IQueryable:

Método de acción Get() retornando un IQueryable

Método de acción Get() retornando un IQueryable

Tal como menciona MSDN, el motivo de esta cambio es que la interfaz IQueryable hereda la interfaz IEnumerable, por lo que si representa una consulta, se pueden enumerar los resultados de esa consulta (la enumeración provoca la ejecución del árbol de expresión asociado a un objeto IQueryable). Es tarea del framework armar la consultas correctamente a partir de las query options enviadas en la URI.

Realizado el cambio, vamos a consumir el servicio como lo veníamos haciendo normalmente utilizando la siguiente URI:

http://localhost:[port]/api/clientes
Datos obtenidos del servicio

Datos obtenidos del servicio

Podemos observar que los resultados vienen en el mismo orden que los habíamos agregamos en el array (es decir, sin estar ordenados por alguna condición). Ahora solicitemos el mismo recurso, especificando que vengan ordenados por el atributo nombre:

http://localhost:[port]/api/clientes?$orderby=Nombre
Datos obtenidos del servicio utilizando las convenciones de URL

Datos obtenidos del servicio utilizando las convenciones de URL

Como vemos, utilizando las convenciones URI, es muy simple establecer condiciones-acciones-funciones en la obtención de los recursos! 🙂

Pero eso no es todo, también podríamos trabajar con paginación y filtros. Simplemente debemos agregar en la URI la query correspondiente de acuerdo a nuestras necesidades, algunos ejemplos:

http://localhost:[port]/api/clientes?$filter=Nombre eq ‘Jous’
  • Filtrar utilizando operadores lógicos:
http://localhost:[port]/api/clientes?$filter=Nombre eq ‘Sebis’ or Nombre eq ‘Jous’
http://localhost:[port]/api/clientes?$top=3&$skip=0

También tenemos disponibles un gran conjunto de opciones de query dentro de las cuales podemos encontrar: Select, Top, OrderBy, Expand, Format, DateTime Functions, Math Functions, Type Functions y muchísimas otras más.

Para finalizar, quería comentarles que OData dispone de un conjunto de API’s de creación y consumo de Servicios OData para trabajar desde el lado del cliente con dispositivos mobiles (WP7, Android, iOS), app webs (Silverligth, ASP.NET, HTML 5 + Javascript, Java, PHP, Ruby) y web CMS (Joomla, Drupal). Y también desde el lado del servidor con custom servers (.NET Server, Java, PHP, Node.JS),  databases (SQL Server, MySql, Azure Data) y cloud app (App Engine, Azure).

Espero que les sea de utilidad.

Nos vemos pronto!

ASP.NET Web API: Validando con Global Action Filters

En esta cuarta entrega sobre ASP.NET Web API veremos como aplicar validaciones a nivel global del proyecto. Si observamos la forma en que manejamos los errores del modelo en el método de acción Post(), podemos identificar un patrón común para todas las validaciones:

Validación del modelo

Validación del modelo

Por lo tanto, porque no gestionarlo de manera global,y despreocuparnos de este tema. ASP.NET MVC nos proporciona un mecanismo para esto, y son los Global Action Filters que nos permiten ejecutar lógica antes o después de un método de acción (sobre este tema ya habíamos hablamos en este post).

Momento de definir el filtro de acción global que llamaremos ValidationActionFilter:

Definición del filtro de acción ValidationActionFilter

Definición del filtro de acción ValidationActionFilter

Acto seguido, registrar el filtro de acción en el método Application_Start() del archivo Global.asax:

Registrando el filtro de acción

Registrando el filtro de acción

Finalmente limpiamos el método de acción Post():

Método de acción Post()

Método de acción Post()

Probemos nuevamente el formulario, y las validaciones deberían actuar de la misma forma:

Validaciones del formulario

Validaciones del formulario

Espero que les haya servido y en próximos post vamos a continuar con más características de ASP.NET Web API.

ASP.NET Web API paso a paso

En el post anterior, hicimos una introducción al estilo de arquitectura REST y la forma de implementarlo utilizando ASP.NET Web API, un tipo de proyecto nuevo que nos provee ASP.NET MVC 4. En esta oportunidad vamos a seguir hablando de ASP.NET Web API y la forma de consumir nuestros servicios REST desde una aplicación web. La invocación a los mismos lo haremos por medio de llamadas AJAX utilizando la librería de Javascript jQuery.

En el ejemplo, construiremos una única página en la cual concentraremos todas las operaciones CRUD que se pueden realizar sobre los clientes (por si no lo recuerdan, el modelo utilizado en el post anterior fue precisamente la entidad Cliente). Es importante resaltar, antes de continuar, que en un mismo proyecto pueden convivir sin problemas una aplicación web ASP.NET MVC y los servicios REST implementados con Web API, por lo que no será necesario generar otro proyecto para tal fin.

A trabajar!… el primer paso será agregar  una nueva vista, que vamos a llamar GestionClientes. Para esto agregamos el método de acción GestionClientes() en el controller HomeController:

Creando el método de acción GestionClientes

Creando el método de acción GestionClientes

Acto seguido, crear la vista correspondiente. Para eso hacemos click derecho sobre el método de acción GestionClientes() y seleccionamos la opción “Add View“. En el dialogo que se nos abre elegimos Razor como ViewEngine y la Master Page que viene por defecto en el proyecto:

Agregando la vista GestionClientes

Agregando la vista GestionClientes

Si vamos a la definición de la master page, nos vamos a encontrar con que ya tenemos registrados todos los archivos de scripts de la carpeta Scripts gracias al sistema de compactación y minimización de scripts y CSS que nos provee ASP.NET MVC 4 (por lo que no hará falta agregar la referencia a las librería de jQuery que necesitamos utilizar):

Caching de bundles

Caching de bundles

En caso de no utilizar la master page por defecto o simplemente están trabajando sobre un documento HTML, agregar la referencia a la librería jQuery (en el ejemplo estamos utilizando la versión jquery-1.6.2.js).

El próximo paso es crear el script JS donde estará la lógica desde la cual vamos a realizar las llamadas AJAX a nuestro servicio REST. Dentro de la carpeta Scripts, agregamos un nuevo ítem JScript File llamado Clientes.js:

Agregando el script Clientes.js

Agregando el script Clientes.js

Para terminar esta primer parte, modificamos la vista GestionClientes.cshtml con la siguiente estructura (no me hago responsable del diseño de la misma :)):

Modificando la vista ClientesGestion

Modificando la vista ClientesGestion

Con este paso ya tenemos todo preparado para empezar. Para seguir un cierto orden en el desarrollo, vamos a ir trabajando con cada una de las operaciones CRUD que habíamos definido en el post anterior.

GET – Obtener la representación de una la lista de clientes

En esta primer operación, la intención es poder recuperar la lista de todos los clientes para visualizarlos en la página. Revisemos la entrada correspondiente:

RECURSO MÉTODO OPERACIÓN URI
Lista de Clientes GET Obtener la representación de una la lista de clientes. http://localhost:%5Bport%5D/Api/Clientes/

Muchos ya se habrán dado cuenta de que lo más simple de hacer es una llamada AJAX (utilizando lógicamente el verbo HTTP GET) y recuperar la lista de clientes para visualizarlos de alguna manera en la página… y están en lo correcto, así que manos a la obra!

El primer paso es actualizar el método de acción Get() del controlador ClientesController:

Definiendo el método de acción Get()

Definiendo el método de acción Get()

En este caso no vamos a trabajar contra una base de datos, ya que la intención del post es mostrar la forma de invocar los servicios REST, por lo que vamos a crear una propiedad en el controlador con una lista de objetos Cliente emulando un simplísimo repositorio de datos.

El segundo paso es escribir la lógica necesaria para recuperar y visualizar los clientes en la página. Para eso vamos a agregar lo siguiente dentro del archivo de script Clientes.js:

Script para recuperar los clientes

Script para recuperar los clientes

Momento de comentarles un poco sobre el código. Lo que hicimos fue crear la función recuperarClientes() desde la cual realizamos la petición AJAX para invocar al método Get() del servicio REST utilizando la función $.getJSON() que nos provee jQuery. A la función $.getJSON() le pasamos dos parámetros: el primero es la URL a la cual se hará la llamada, y el segundo una función de callback que se ejecutará una vez que este lista la respuesta del servidor. La función de callback recibirá en una colección de objetos – clientes – JSON el cual vamos a recorrer para armar el HTML que se mostrará en la página (pueden notar que en este caso la negociación cliente-servidor determina que la respuesta no sea un XML, como en el post anterior, sino que sea en formato JSON).

Si ejecutamos la aplicación, y entramos a la página recién creada, veremos la lista de clientes obtenidas desde el servicio ;). Es importante entender que la llamada al servicio se hizo por medio del verbo HTTP GET, y solo tuvimos que especificar la URL del servicio – ‘/api/clientes/’ – sin necesidad de especificar el nombre del método que necesitábamos (internamente el servidor mapeará la petición realizada con el verbo HTTP GET – y sin parámetros -, con el método de acción Get() del controlador ClientesController).

Recuperando y visualizando la lista de clientes

Recuperando y visualizando la lista de clientes

GET – Obtener la representación de un cliente

La segunda operación con la que vamos a trabajar es la búsqueda de un cliente por el Id. Repasemos la operación correspondiente:

RECURSO MÉTODO OPERACIÓN URI
Cliente GET Obtener la representación de un cliente. http://localhost:%5Bport%5D/Api/Clientes/5

A diferencia del método anterior, puede ocurrir que devolvamos un resultado, o que invoquemos al servicio con un Id de un cliente inexistente. En este último caso se debería informar al usuario de dicha situación. Como los servicios web basados en REST intentan trabajar de manera similar al protocolo HTTP, podemos hacer uso de los códigos de estado HTTP  para informa acerca de estos casos. Por ejemplo, podríamos utilizar el código de estado HTTP 404 Not Found si se intenta recuperar un cliente que no existe, y un código de estado HTTP 500 Internal Server Error si ocurrió un error en el procesamiento (este último en realidad ocurre sin necesidad de especificarlo).

Aclarado esto, trabajemos sobre nuestro el método de acción correspondiente:

Definiendo el método de acción Get(int id)

Definiendo el método de acción Get(int id)

Modificamos la vista:

Modificando la vista ClientesGestion

Modificando la vista ClientesGestion

Ahora, es el momento de trabajar nuevamente sobre nuestro script:

Agregando lógica al script Clientes.js

Agregando lógica al script Clientes.js

Veamos rápidamente el código que agregamos al scritp. Antes que nada definimos el evento click del botón “Buscar”  – ver la parte final del código-. En dicho evento vamos a recuperar el Id del cliente que el usuario ingreso en la caja de texto con el atributo Id=“IdCliente” – selector $(‘#IdCliente’). Luego llamamos a la función buscarCliente(id, callback) pasándole además del Id del cliente, una función de callback que se ejecutará en caso de que la búsqueda sea exitosa. Esta función de callback recibirá como parámetro nuestro un objeto cliente – serealizado en  formato JSON – que usaremos para armar la porción de HTML que visualizaremos en la página.

La función buscarCliente(id, callback) recibe como parámetro el Id del Cliente que queremos recuperar, y a partir de ese dato hace la invocación AJAX al servicio. Dentro de los parámetros vamos ha indicar: la URL del servicio – url:‘/api/clientes/’-,  los parámetros que espera el servicio – { id : id } – (el cual va permitir al servidor identificar cual de los dos métodos GET llamar), el verbo HTTP – type:“GET” – y el formato de respuesta eperado – contentType:“application/json;charset=utf-8″.

Un punto importante a tener en cuenta es la forma en que vamos a procesar la respuesta del servicio. Un buen recurso que nos provee la función $.ajax de jQuery es que podemos invocar distintas funciones a partir del código de estado – “statusCode” – que retorne el servicio! 🙂 En este caso, si el código de estado HTTP es 200 OK, invocamos a la función de callback para visualizar la información por pantalla. Por el contrario si el código de estado HTTP es 404 Not Found, le podemos informar al usuario que no se encontró el cliente. También podríamos procesar el código de estado HTTP 500 Internal Server Error cuando ocurran problemas del lado del servidor para notificar al usuario (lo dejo como tarea para el hogar).

Veamos un ejemplo cuando buscamos un cliente que existe:

Búsqueda de clientes en la vista

Búsqueda de clientes en la vista

Ahora un ejemplo intentando buscar un cliente inexistente:

Cliente no encontrado!

Cliente no encontrado!

POST – Crear un cliente

Ahora llego el momento de poder crear un nuevo cliente. Inspeccionemos la entrada:

RECURSO MÉTODO OPERACIÓN URI
Cliente POST Crear un cliente. http://localhost:%5Bport%5D/Api/Clientes/{cliente}

Empecemos con el método de acción, el cual va a tener la siguiente estructura:

Definiendo el método de acción Post

Definiendo el método de acción Post

Respecto de las operaciones anteriores, la definición de este método es algo diferente. Pueden ver que en este caso, el parámetro que recibe es el cliente que queremos crear (veremos mas adelante como enviarlo). La respuesta también es algo diferente a lo que veníamos trabajando. En este caso, luego de que hayamos creamos el nuevo recurso (cliente) vamos a armar el mensaje de respuesta HTTP que viajará en el encabezado de la misma y que contendrá, entre otras cosas, la ubicación del nuevo recurso (el cual se encuentra bajo la URI “/api/clientes/idNuevoCliente”) y el código de estado que corresponde a dicha operación: HTTP 201 Created (HttpStatusCode.Created).

En la vista vamos a agregar lo siguiente:

Actualizando la vista GestionClientes

Actualizando la vista GestionClientes

Momento de trabajar nuevamente en el script:

Actualizando el script Clientes.js

Actualizando el script Clientes.js

En cuanto a la asignación al evento “click” del botón “Crear cliente” es muy similar a la que hicimos en la búsqueda de clientes. La función que vamos a invocar es crearCliente(nuevoCliente, callback) y la función de callback que le pasaremos mostrará en una ventana modal el Id del nuevo cliente. En esta caso la función no espera un Id, lo que  debemos pasarle es un objeto javascript con la estructura de la entidad Cliente, que luego será serealizado y enviado al servicio.

Dentro de la función crearCliente, lo que vamos a hacer es una invocación AJAX, utilizando el verbo HTTP POST (la cual se mapeará con el método Post() del servicio). En los parámetros – data – vamos a enviar los datos del cliente aplicándole la función JSON.stringify, la cual nos va a permitir serializar nuestro objeto javascript a JSON string. El resto es historia conocida, solo que este caso nos importa el código de estado HTTP 201 Create para invocar a la función de callback.

Vamos a crear el cliente:

Creando un cliente

Creando un cliente

Cargamos el nombre del cliente y presionamos “Crear”:

Cliente creado existosamente

Cliente creado existosamente

POST – Actualizar un cliente

La próxima operación con la que vamos a trabajar en la actualización de un cliente. Revisemos la tabla:

RECURSO MÉTODO OPERACIÓN URI
Cliente POST Actualizar un cliente. http://localhost:%5Bport%5D/Api/Clientes/{cliente}

Como vemos, el verbo HTTP que vamos a utilizar en esta operación es PUT. Trabajemos entonces en el método de acción correspondiente:

Definiendo el método de acción Put()

Definiendo el método de acción Put()

A diferencia del método POST, este no retorna ningún resultado. Solamente en el caso de que el cliente no exista, devolveremos el código de estado HTTP 404 Not Found.

En la vista agregamos lo siguiente:

Modificando la vista GestionClientes

Modificando la vista GestionClientes

Y agregamos al script la lógica necesaria para poder actualizar un cliente:

Actualizamos el script Clientes.js

Actualizamos el script Clientes.js

Lo que hicimos es muy similar a la creación de un cliente. El cambio más importante, es que la llamada la hacemos utilizando el verbo HTTP PUT.

Ejemplo de la edición de un cliente:

Editando un cliente

Editando un cliente

DELETE – Eliminar un cliente

La última operación en la que vamos a trabajar es la eliminación de un cliente. Revisemos la tabla:

RECURSO MÉTODO OPERACIÓN URI
Cliente DELETE Eliminar un cliente. http://localhost:%5Bport%5D/Api/Clientes/5

Trabajemos sobre el método de acción correspondiente a esta operación:

Definiendo el método de acción Delete()

Definiendo el método de acción Delete()

La lógica del método de acción es bastante simple, el primer paso es validar que el cliente que intentamos eliminar exista (de lo contrario retornamos un mensaje con el código de estado HTTP 404 Not Found). De ser afirmativo, realizamos la eliminación propiamente dicha y retornamos un mensaje con el código de estado HTTP 204 No Content.

En la vista agregamos lo siguiente:

Modificando la vista GestionClientes

Modificando la vista GestionClientes

Modifiquemos por última vez el script:

Modificando el script Clientes.js

Modificando el script Clientes.js

A esta altura, no habrá notado nada raro en esta implementación ;). Probemos:

Eliminando un cliente

Eliminando un cliente

Resumiendo, la intención de este post fue mostrarles como podemos realizar un simple AMB de clientes utilizando Web API para exponer nuestros servicios REST y jQuery para consumirlos desde el cliente. También mostrarle la importancia de los verbos HTTP para describir las distintas operaciones que podemos realizar sobre los recursos, y no quedarnos simplemente en el uso de los verbos GET o POST para tal fin.

En próximos post vamos a ver como integrar Web API con el mecanismo de routing, el soporte de Model Bindings, Validations y Actions Filters y como integrar OData.

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.