Creación de una plantilla de API web RESTful en .NET Core 1.1 – Parte n.º 1:devolución de códigos HTTP

 C Programming >> Programación C >  >> Tags >> API
Creación de una plantilla de API web RESTful en .NET Core 1.1 – Parte n.º 1:devolución de códigos HTTP

Creé API RESTful con .NET Framework y WebAPI antes, pero todavía no tengo nada comercial con .NET Core. .NET Core ha estado disponible por un tiempo:la versión 1.1 se lanzó en Connect(); //2016:he oído que algunos clientes ahora están dispuestos a experimentar con esto para lograr algunas de las ganancias potenciales de rendimiento y estabilidad.

Para prepararme para las solicitudes de nuevos clientes, he estado experimentando con la creación de una API RESTful simple con .NET Core para ver cuán diferente es a la versión alternativa con .NET Framework normal... y descubrí que es realmente bastante diferente.

Ya he escrito sobre algunos de los desafíos en la actualización de .NET Core 1.0 a 1.1 al crear un nuevo proyecto; esta publicación trata sobre cómo comenzar con la plantilla predeterminada para proyectos de API web y transformarla en algo que se parece más a un proyecto útil para alojar microservicios RESTful.

Esta primera publicación de la serie trata sobre cómo convertir el proyecto predeterminado en un buen ciudadano HTTP y devolver códigos de estado HTTP.

Cuando creo un nuevo proyecto de WebAPI con .NET Core 1.1 a partir de la plantilla predeterminada de Visual Studio, se crean varios archivos en el proyecto. El más interesante es el "ValuesController":contiene los verbos estándar asociados con los servicios RESTful, GET, POST, PUT y DELETE. He pegado el código predeterminado creado a continuación:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
 
namespace MyWebAPI.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
 
        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }
 
        // POST api/values
        [HttpPost]
        public void Post([FromBody]string value)
        {
        }
 
        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }
 
        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

Sin embargo, una de las cosas que no me gusta de esto y que sería muy fácil de cambiar es el tipo de retorno de cada verbo. Un buen servicio RESTful debería devolver códigos de estado HTTP que describan el resultado de la acción; por lo general, 200 códigos para el éxito:

  • 200:la solicitud está bien;
  • 201:recurso creado correctamente;
  • 202:se aceptó la actualización y se procesará (aunque es posible que se rechace);
  • 204:solicitud procesada y no hay contenido para devolver.

Además, las respuestas a las acciones RESTful a veces contendrán información:

  • 200 – OK – si la acción es GET, la respuesta contendrá un objeto (o una lista de objetos) que fueron solicitados.
  • 201 – Creado – la respuesta contendrá el objeto que se creó y también el URI único requerido para obtener ese objeto.
  • 202 – Aceptado – la respuesta contendrá el objeto para el que se solicitó una actualización.
  • 204 – Sin contenido para devolver:esto podría devolverse como resultado de una solicitud de eliminación, donde no tendría sentido devolver un objeto (ya que teóricamente ya no existe).

Creo que el ValuesController predeterminado sería más útil si implementara un patrón de devolución de respuestas con códigos de estado HTTP correctamente configurados, y creo que el primer paso hacia esto sería usar el código predeterminado a continuación para ValueController (que, como plantilla predeterminada – obviamente no hace nada útil todavía).

using Microsoft.AspNetCore.Mvc;
 
namespace MyWebAPI.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public IActionResult Get()
        {
            return Ok(new string[] { "value1", "value2" });
        }
 
        // GET api/values/5
        [HttpGet("{id}")]
        public IActionResult Get(int id)
        {
            return Ok("value");
        }
 
        // POST api/values
        [HttpPost]
        public IActionResult Post([FromBody]string value)
        {
            return Created($"api/Values/{value}", value);
        }
 
        // PUT api/values/5
        [HttpPut("{id}")]
        public IActionResult Put(int id, [FromBody]string value)
        {
            return Accepted(value);
        }
 
        // DELETE api/values/5
        [HttpDelete("{id}")]
        public IActionResult Delete(int id)
        {
            return NoContent();
        }
    }
}

Los principales cambios que he realizado hasta ahora son:

  • El tipo de retorno de cada acción ahora es IActionResult, que permite que se devuelvan códigos de estado Http.
  • Para las acciones GET, acabo de envolver los objetos devueltos (que son cadenas simples) con el resultado Ok.
  • Para la acción POST, he usado el objeto de resultado Creado. Esto es diferente a Aceptar porque además de incluir un objeto, también incluye un URI que apunta a la ubicación del objeto.
  • Para la acción PUT, simplemente envolví el objeto devuelto con el resultado Aceptado. El tipo de retorno de Aceptado es nuevo en .NET Core v1.1; no se compilará si tiene como destino versiones anteriores.
  • Finalmente, para la acción DELETE, en lugar de devolver void, devolví un tipo de resultado Sin contenido.

Realmente me gusta cómo .NET Core v1.1 crea excelentes servicios RESTful de una manera limpia y simple, y lo prefiero a la forma en que se usaba anteriormente en .NET. Estoy planeando otras publicaciones que se centrarán en algunos aspectos funcionales y no funcionales de la creación de un servicio RESTful limpio:

  • Cómo probar este servicio utilizando un cliente ReST;
  • Cómo implementar este servicio en un contenedor Docker;
  • Cómo mejorar la forma en que el servicio busca;
  • Cómo mejorar el rendimiento de su servicio;
  • Cómo proteger los encabezados de la respuesta;
  • Cómo documentar esta clase usando Swagger y Swashbuckle;
  • Cómo acceder a este servicio web desde JQuery.

Sobre mí: Regularmente publico sobre .NET; si está interesado, síganos en Twitter o eche un vistazo a mis publicaciones anteriores aquí. ¡Gracias!