Tipos de respuesta y plantillas en NancyFx

En los artículos anteriores de la serie, hacíamos un breve repaso a cómo crear módulos y rutas con NancyFx, en este veremos cómo responder a las peticiones usando texto plano, JSON o ficheros, así como usar un viewengine que nos permita, a través de plantillas, usar elementos generados por el servidor en documentos HTML.

Presentando al Content-Type

El Content-type es un mensaje que forma parte de los encabezados HTTP y especifica el tipo de recurso que soliticamos y que se devuelve en una respuesta para que el navegador lo pueda procesar. De esa manera, un content-type de tipo text/html se procesará en el cliente como un fichero HTML a renderizar, el tipo application/octet-stream se referirá habitualmente a un fichero binario, y así para ficheros de audio, vídeo u otros.

Nancy permite especificar el tipo de contenido que estamos devolviendo, de esta manera podemos rescatar el ejemplo anterior donde especificábamos el código de retorno, y modificarlo para que devuelva un contenido con un tipo mime específico:

public class ResponseTypes : NancyModule
{
	public ResponseTypes ()
	{
		Get["/responses/text"] = _ => {
			return ((Response)"<h1>Texto plano</h1>\n").
				WithContentType("text/plain");
		};

		Get["/responses/html"] = _ => {
			return ((Response)"<h1>Texto HTML</h1>\n").
				WithContentType("text/html");
		};

		Get["/responses/binary"] = _ => {
			return ((Response)"<h1>Texto en un fichero</h1>\n").
				WithContentType("application/octet-stream");
		};
	}
}

En este caso, la primera respuesta, aunque espefiquemos código HTML, mostrará el texto plano, en la segunda hemos especificado que se trata de html, con lo cual la respuesta se renderizará por pantalla. En la tercera respuesta, hemos establecido el tipo a binario, con lo cual la acción a realizar será la de descargar el contenido a un fichero en disco.

JSON

Javascript Object Notation, o JSON, es un viejo conocido de este blog, ya que lo hemos usado para acceder a Azure Mobile Services, a Twitter, y a otros. Es una representación ligera de datos que tiene un formato similar a este:

{
    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "address": {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": 10021
    },
    "phoneNumbers": [
        {
            "type": "home",
            "number": "212 555-1234"
        },
        {
            "type": "fax",
            "number": "646 555-4567"
        }
    ]
}

Una de las cosas que nos permite NancyFx, es codificar en formato Json un objeto (o un conjunto de ellos) para devolverlos al cliente. Veamos un ejemplo:

public class Person
{
	public string Name {
		get;
		set;
	}
	public string Surname {
		get;
		set;
	}
}public class JsonResponse : NancyModule
{
	public JsonResponse ()
	{
		Get["/json/single"] = _ => Response.AsJson(
			new Person()
			{
				Name = "Roberto",
				Surname = "Luis"
			}
		);
	}
}

En este ejemplo, creamos un objeto, y usando Response.AsJson codificamos su contenido en formato Json y lo devolvemos. La respuesta, si la viésemos en un navegador, tendría este aspecto:

{
    "Name": "Roberto",
    "Surname": "Luis"
}

Si examinamos cuidadosamente la cabecera de la respuesta (usando curl por ejemplo), veremos además el valor del campo Content-Type:

Content-Type: application/json; charset=utf8

Lo que ha ocurrido es que Nancy automáticamente ha gestionado las cabeceras por nosotros. Contamos además con métodos como AsXml, AsImage o AsFile para devolver nuestros objetos en otros formatos.

ViewEngines

Un view engine, o motor de vistas, es un componente que nos permite combinar plantillas HTML con llamadas al servidor, evitandonos el engorro de trabajar directamente con html dentro del código, y posiblitando una separación de responsabilidades. Nancy incluye uno por defecto, llamado “Super Simple View Engine”, que permite tener una plantilla de este estilo:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"> <title>External template</title>
  </head>
  <body>
    <h1>Hello,[email protected]!</h1>
    <ul>
    @Each.Model.Children
    <li>@Current</li>
      @EndEach
    </ul>
  </body>
</html>

Los campos @Model.Name y @Model.Children, nos pueden recordar a Razor, el motor de vistas de ASP.net MVC3, mientras el uso de @Each.Model nos pueden recordar a las plantillas erb de ruby. Estos elementos nos permiten agregar datos de manera dinámica a un documento HTML.

La variable @Model, a la que hemos accedido desde la vista, se define desde el controlador, y puede ser un objeto perteneciente a una clase, o como se muestra en el ejemplo, un objeto anónimo que contenga los datos que necesitamos:

public class ViewTemplates : Nancy.NancyModule
{
	public ViewTemplates ()
	{
		Get ["/ViewEngines/WithData"] = _ => {
			var model = new { 
				Name = "John Smith", 
				Children = new []{"Mike", "Bob", "James"}
			};
			return View["ViewEngines/TemplateWithData.html", model];
		};
	}
}

Finalmente, se devuelve la vista usando la ruta relativa de la misma, y el objeto que servirá de modelo.

Resumen

En este artículo se ha visto cómo podemos personalizar el tipo de respuesta, ya sea texto, binario, o JSON, así como usar un motor de vistas para separar la vista del controlador. Con este artículo terminamos esta serie de introducción a NancyFx, si deseas consultar más información, aquí están los artículos anteriores de la serie:

Enlaces adicionales

Un pensamiento en “Tipos de respuesta y plantillas en NancyFx

  1. Pingback: if (2013.IsComplete) 2014.StartAsync(); | rlbisbe @ dev

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