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.

21 comentarios en “ASP.NET Web API paso a paso

  1. Esta muy bien.
    Me funciona todo, pero claro, al cliente le llega todo el código jQuery con mucha información y tendríamos que hacer que solo se descargue el código jQuery que nos interese en cada momento ¿no?
    ¿como se puede solucionar esto?

    • Paco, lo que podes hacer es una “minificación” del script (de esta forma al cliente le llega el código de script lo mas “liviano” y “comprimido” posible).

      En ASP.NET MVC 4 tenes la posibilidad de hacer esto usando la feature “Bundling and Minification” (Bundlign es el proceso de combinar todos los archivos de JS o CSS en uno solo y Minification el de reducir estos archivos, eliminando espacios en blancos, saltos de línea, acortar el nombre de variables, etc).

      Te paso el link para más detalle: http://theshravan.net/bundling-and-minification-support-in-asp-net-mvc-4/

      Abrazos!

  2. Holamuy buen ejemplo, excelente explicacion detallada y clara, me gustaria saber como poder relacionar esta parte para poder obtener datos de una Base de datos. Gracias

    • Hola David.

      Lo que tenes que hacer es modificar la parte que trabaja con datos estáticos por la lógica que te permite trabajar contra una DB. Por ejemplo en el método get tendrías algo como lo siguiente:

      public Cliente Get(int id)
      {
      return ClientService.GetClient(id);
      }

      Dentro de ClientService.GetClient(…) tendrías la lógica que: se conecta contra la DB, recupera la información de la base de datos y retorna el una nueva instancia del objeto cliente con los datos correspondiente.

      Abrazos!

  3. Hola Sebis:
    Muy interesante tu blog, felicitaciones.
    Te cuento que estoy desarrollando un Framework y lo acabo de adaptar para ASP.Net MVC4 Web Api.
    Estoy buscando gente para compartir ideas, y por que no, algo de desarrollo.
    Así que si tenes tiempo y ganas te invito pases por mi blog, veas lo que hago y compartamos algunas experiencias.

    Saludos

    Bruno

    • Hola Bruno, antes que nada gracias por el comentario!
      Muy interesante el framework en el que estas trabajando, podes contar conmigo en lo que necesites. Vengo un poco complicado de tiempos, pero podemos hacernos un lugarcito 😉
      Abrazos!

      • Buenísimo Sebis.
        Lo que necesito es gente con experiencia que simplemente use el Framework para poder tener algo de feedback.
        En pocas palabras, necesito críticas constructivas para hacer de esta herramienta algo realmente útil.
        Si bien mis compañeros y yo la estamos usando y nos da muy buenos resultados, la onda es que otras visiones y diferentes escenarios podrían enriquecer el trabajo.
        Ahora, si te interesa y ves que te sirve, también podrías participar del desarrollo, y si no querés codificar, podrías incluir tu visión y ser parte des esto de todas maneras.

  4. Hola he probado el ejemplo, pero no consigo que escriba el javascrip. En el primer get, el que recupera todos los clientes, el javascript no escribe nada en el tag.

    Podrías subir el código de un proyecto funcionando a ver si veo mi error?? Es que llevo ya 2 días buscando porque no funciona…

    Gracias ^_^

  5. Hola amigo buen aporte… amigo queria pedirte si puedes hacer un CRUD con jquery en ASP.NET MVC3 utilizando formularios modales.. espero y me respondas..

    • Hola Alvaro, disculpa la demora pero estoy con varios asuntos juntos 🙂
      No estoy seguro a que te referís con “una página diferente”, pero si es lo que pienso simplemente podes crear una vista para cada operación CRUD e invocar en cada una al método que corresponda. Se entiende? o no es lo que estas buscando?

  6. Buen día estimado.
    Muchas gracias por el trabajo.
    Estuve desarrollando los codigos de este tutorial, y me encontre con algunos problemas pequeños, en particular con el DELETE, dado que me dice que no puede llegar a la ruta
    /api/clientes y envia un not found.
    Es posible que me envies los fuentes para poder encontrar el problema por favor.
    Saludos.

    angelo.gonzalez@live.com

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s