0

Mejores Prácticas: APIs #1

Desde hace un tiempo, para nosotros los programadores de .net y C#, tenemos disponible en ASP.Net Web API. Este nos permite poder ejecutar API Rest en cualquier entorno sea linux, windows o mac que pueden ser consumidos por nuestros sitios web o aplicaciones móviles.

Muchos me han preguntado sobre buenas prácticas en la creación y el uso de estas nuestras API, por esta razón, recolecte algunas recomendaciones para ustedes veamos.

Usar los estados de HTTP

Luego de realizar una petición el servidor nos devolverá un estado HTTP a nuestra aplicación. Existen varios código de estado el cual podemos devolver y cada uno indica una situación particular que ayudará al cliente a entender que es lo que está sucediendo. Por ejemplo, si estamos haciendo una solicitud GET y retorna valores, el servidor nos responderá con un 200 OK, en caso de no encontrar nada para retornar nos devolverá un 404 No Encontrado.

Si no utilizamos el código correcto el cliente no responderá de una forma esperada. En el ejemplo anterior si en lugar de retornar un estado 404 retornamos un 200, nuestro cliente podría interpretar que todo está correcto produciendo un error.

Ahora supongamos que hay un error en nuestro servicio, como por ejemplo la base de datos está fallando o un servicio tercero no está respondiendo. Si devolvemos un error 200 nuestro cliente entiende que todo está correcto, pero en realidad, la aplicación está fallando internamente. En este caso debemos retornar un error 500 Internal Server Error que le indicará al cliente que la aplicación está teniendo un error en alguno de sus componentes dando la oportunidad de poder notificar al usuario que hay un error que intente más tarde.

Veamos un listado de estados disponibles http:

Information responses

  • 100 Continue, esta respuesta provisional indica que el cliente debe continuar con la solicitud o ignorar la respuesta si la solicitud ya ha finalizado..
  • 101 Switching Protocols, este código se envía en respuesta a un encabezado de solicitud de actualización del cliente e indica el protocolo al que está cambiando el servidor..
  • 103 Early Hints, este código de estado está pensado principalmente para usarse con el encabezado Link, lo que permite que el agente de usuario comience a precargar recursos mientras el servidor prepara una respuesta.

Successful responses

  • 200 Ok, la solicitud se realizó correctamente. El significado del resultado de «éxito» depende del método HTTP:
    • GET: el recurso se ha recuperado y transmitido en el cuerpo del mensaje.
    • HEAD: los encabezados de representación se incluyen en la respuesta sin ningún cuerpo del mensaje.
    • PUT o POST: El recurso que describe el resultado de la acción se transmite en el cuerpo del mensaje.
    • TRACE: el cuerpo del mensaje contiene el mensaje de solicitud tal como lo recibió el servidor.
  • 201 Created, la solicitud se realizó correctamente y, como resultado, se creó un nuevo recurso. Esta suele ser la respuesta enviada después de las solicitudes POST o PUT.
  • 202 Accepted, la solicitud se ha recibido, pero aún no se ha dado curso a ella. No se compromete, ya que no hay forma en HTTP de enviar posteriormente una respuesta asíncrona que indique el resultado de la solicitud. Está pensado para los casos en que otro proceso o servidor maneja la solicitud, o para el procesamiento por lotes.
  • 203 Non-Authoritative Information, este código de respuesta significa que los metadatos devueltos no son exactamente los mismos que están disponibles en el servidor de origen, sino que se recopilan de una copia local o de terceros. Esto se utiliza principalmente para réplicas o copias de seguridad de otro recurso. Excepto en ese caso específico, 200 OK se prefiere la respuesta a este estado. 
  • 204 No Content, No hay contenido para enviar para esta solicitud, pero los encabezados pueden ser útiles. El agente de usuario puede actualizar sus encabezados almacenados en caché para este recurso con los nuevos.
  • 205 Reset Content, Indica al agente de usuario que restablezca el documento que envió esta solicitud.
  • 206 Partial Content, Este código de respuesta se utiliza cuando el encabezado Range se envía desde el cliente para solicitar sólo una parte de un recurso.

Redirection messages

  • 300 Multiple Choices, la solicitud tiene más de una respuesta posible. El agente de usuario o usuario debe elegir uno de ellos. (No existe una forma estandarizada de elegir una de las respuestas, pero se recomiendan enlaces HTML a las posibilidades para que el usuario pueda elegir).
  • 301 Moved Permanently, la dirección URL del recurso solicitado se ha cambiado permanentemente. La nueva URL se da en la respuesta.
  • 302 Found, este código de respuesta significa que el URI del recurso solicitado se ha cambiado temporalmente. Es posible que se realicen más cambios en el URI en el futuro. Por lo tanto, este mismo URI debe ser utilizado por el cliente en futuras solicitudes.
  • 303 See Other, el servidor envió esta respuesta para indicar al cliente que obtuviera el recurso solicitado en otro URI con una solicitud GET.
  • 304 Not Modified, esto se utiliza para fines de almacenamiento en caché. Le dice al cliente que la respuesta no se ha modificado, por lo que el cliente puede seguir usando la misma versión en caché de la respuesta.
  • 307 Temporary Redirect, el servidor envía esta respuesta para dirigir al cliente a obtener el recurso solicitado en otro URI con el mismo método que se utilizó en la solicitud anterior. Esto tiene la misma semántica que el 302 Found Código de respuesta HTTP, con la excepción de que el agente de usuario no debe cambiar el método HTTP utilizado: si un POST se utilizó en la primera solicitud, se debe utilizar una solicitud en la segunda.POST
  • 308 Permanent Redirect, esto significa que el recurso ahora se encuentra permanentemente en otro URI, especificado por el Location: Encabezado de respuesta HTTP. Esto tiene la misma semántica que el 301 Moved Permanently Código de respuesta HTTP, con la excepción de que el agente de usuario no debe cambiar el método HTTP utilizado: si un POST se utilizó en la primera solicitud, se debe utilizar una solicitud en la segunda.POST

Client error responses

  • 400 Bad Request, El servidor no puede o no procesará la solicitud debido a algo que se percibe como un error del cliente (por ejemplo, sintaxis de solicitud con formato incorrecto, trama de mensaje de solicitud no válida o enrutamiento de solicitud engañoso).
  • 401 Unauthorized, Aunque el estándar HTTP especifica «no autorizado», semánticamente esta respuesta significa «no autenticado». Es decir, el cliente debe autenticarse para obtener la respuesta solicitada.
  • 402 Payment Required Experimental, Este código de respuesta está reservado para uso futuro. El objetivo inicial para crear este código era usarlo para sistemas de pago digital, sin embargo, este código de estado se usa muy raramente y no existe una convención estándar.
  • 403 Forbidden, El cliente no tiene derechos de acceso al contenido; es decir, no está autorizado, por lo que el servidor se niega a dar el recurso solicitado. A diferencia de , la identidad del cliente es conocida por el servidor401 Unauthorized.
  • 404 Not Found, El servidor no puede encontrar el recurso solicitado. En el navegador, esto significa que no se reconoce la URL. En una API, esto también puede significar que el punto de enlace es válido pero que el recurso en sí no existe. Los servidores también pueden enviar esta respuesta en lugar de 403 Forbidden para ocultar la existencia de un recurso a un cliente no autorizado. Este código de respuesta es probablemente el más conocido debido a su frecuente aparición en la web.
  • 405 Method Not Allowed, El método de solicitud es conocido por el servidor, pero no es compatible con el recurso de destino. Por ejemplo, es posible que una API no permita calling DELETE para eliminar un recurso.
  • 406 Not Acceptable, Esta respuesta se envía cuando el servidor web, después de realizar la negociación de contenido controlada por el servidor, no encuentra ningún contenido que se ajuste a los criterios dados por el agente de usuario.
  • 407 Proxy Authentication Required, Esto es similar a 401 Unauthorized Pero la autenticación es necesaria para ser realizada por un proxy.
  • 408 Request Timeout, Esta respuesta es enviada en una conexión inactiva por algunos servidores, incluso sin ninguna solicitud previa por parte del cliente. Significa que el servidor desea cerrar esta conexión no utilizada. Esta respuesta se usa mucho más ya que algunos navegadores, como Chrome, Firefox 27+ o IE9, utilizan mecanismos de pre conexión HTTP para acelerar la navegación. También tenga en cuenta que algunos servidores simplemente cierran la conexión sin enviar este mensaje.
  • 414 URI Too Long, El URI solicitado por el cliente es más largo de lo que el servidor está dispuesto a interpretar.
  • 415 Unsupported Media Type, El formato multimedia de los datos solicitados no es compatible con el servidor, por lo que el servidor rechaza la solicitud.

Server error responses

  • 500 Internal Server Error, El servidor se ha encontrado con una situación que no sabe cómo manejar.
  • 501 Not Implemented, El método de solicitud no es compatible con el servidor y no se puede controlar. Los únicos métodos que los servidores deben admitir (y, por lo tanto, que no deben devolver este código) son GET and HEAD.
  • 502 Bad Gateway, Esta respuesta de error significa que el servidor, mientras trabajaba como puerta de enlace para obtener la respuesta necesaria para manejar la solicitud, obtuvo una respuesta no válida.
  • 503 Service Unavailable, El servidor no está listo para manejar la solicitud. Las causas comunes son un servidor que está inactivo por mantenimiento o que está sobrecargado. Tenga en cuenta que junto con esta respuesta, se debe enviar una página fácil de usar que explique el problema. Esta respuesta debe utilizarse para las condiciones temporales y el Retry-After El encabezado HTTP debe, si es posible, contener el tiempo estimado antes de la recuperación del servicio. El webmaster también debe tener cuidado con los encabezados relacionados con el almacenamiento en caché que se envían junto con esta respuesta, ya que estas respuestas de condición temporal generalmente no deben almacenarse en caché.
  • 504 Gateway Timeout, Esta respuesta de error se da cuando el servidor actúa como puerta de enlace y no puede obtener una respuesta a tiempo.

Existen muchos más. Pueden consultar los que quedaron afuera y las compatibilidades con los navegadores y dispositivos desde aquí.

Desde C# tenemos varios métodos que podemos utilizar para manipular estos estados y retornar los valores correctos:

HTTP Status Code 200 (HTTP Response OK)
[HttpPost]public IActionResult MyMethod(MyModel model){
return Ok();
}
HTTP Status Code 201 (HTTP Response Created)
[HttpPost]public IActionResult MyMethod(MyModel model){    
return Created();
}
HTTP Status Code 204 (HTTP Response No Content)
[HttpPost]public IActionResult MyMethod(MyModel model){
    return NoContent();
}
HTTP Status Code 400 (HTTP Response Bad Request)
[HttpPost]public IActionResult MyMethod(MyModel model){
    return adRequest();
}
HTTP Status Code 401 (HTTP Response Unauthorized)
[HttpPost]public IActionResult MyMethod(MyModel model){
    return Unauthorized();
}
HTTP Status Code 403 (HTTP Response Forbidden)
[HttpPost]public IActionResult MyMethod(MyModel model){
    return Forbid();
}
HTTP Status Code 404 (HTTP Response NotFound)
[HttpPost]public IActionResult MyMethod(MyModel model){
    return NotFound();
}

Estos son los más utilizados. En caso de necesitar o querer utilizar otros código tenemos 2 caminos para devolver. El primero por medio de StatusCode indicando el número o por medio de una enumeración también por StatusCode.

Valor Directo
[HttpPost]public IActionResult MyMethod(MyModel model){
    return StatusCode(302);
}
Using StatusCodes Enum
[HttpPost]public IActionResult MyMethod(MyModel model){
    return StatusCode(Microsoft.AspNetCore.Http.StatusCodes.Status302Found);
}

Formatos coherentes

Es importante siempre pensar en los consumidores de nuestra API. Dependiendo de nuestras respuestas los clientes de las API reaccionan y si nuestras respuestas no son consistentes sus aplicaciones fallan y les haremos la vida muy difícil.

Por otra parte, tener una estructura consistente en nuestras API nos ayudará a documentar más fácilmente. Si respetamos el formato de nuestra respuesta será más sencillo para los desarrolladores comprender lo que obtendrán de cada uno de los servicios. También, será posible crear algún mecanismo automático para las respuestas y no tener una resolución para cada uno de los formatos.

Conclusiones

Hasta aquí hemos visto algunas de las mejores prácticas para el desarrollo correcto de nuestros servicios APIs en .Net 6 o superior. Muchos de estos no son solamente útiles en .Net, es posible llevarlos a otros lenguajes, como por ejemplo, Test de Unidad debido a que son principios.

Si deseas agregar alguna práctica más que recomiendas como importante. Dejame el comentario y con gusto lo haré. Gracias.

Fernando Sonego

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *