¿Cómo diseñar una mejor API?



Los amigos que no entienden RESR también pueden leer

No importa si es un desarrollador front-end y back-end, se encontrará con el diseño de API más o menos en el proceso de diseño de programas. Sin embargo, no es fácil diseñar una API fácil de usar y de mantener ( por supuesto que no todo el mundo piensa así). Al crear una API desde cero, hay muchos detalles que debe tener en cuenta y tener en cuenta. Desde consideraciones básicas de seguridad hasta el uso del método HTTP correcto, autenticación, decidir qué solicitudes y respuestas debe aceptar y devolver, etc.... y la lista continúa.


Así que hoy voy a hacer todo lo posible para condensar todo lo que sé sobre lo que es una buena API y compartirlo con ustedes (por supuesto, no se aplica a todos, así que solo comparto mi opinión). Esta publicación es independiente del lenguaje de programación utilizado, por lo que se aplican a cualquier marco o tecnología.




1. Usar fechas UTC ISO 8601

Cuando se trata de fechas y horas, la API recomienda siempre devolver cadenas en formato ISO 8601 .

Es importante que la aplicación cliente muestre la fecha correcta en una zona horaria específica cuando está en uso, y los datos son más fáciles de manejar.

{
    
    
    "article_writing_time": "2022-03-07T14:30:54.149Z"
}


2. Desarrollar soluciones de alta disponibilidad para API importantes

Para algunas API importantes, como la liquidación del carrito de compras, es imposible depurar cada problema hasta que el servicio al cliente pierde interés.

Por lo tanto, sugiero GET /healthproporcionar para determinar si está en buen estado. Otras aplicaciones, como los balanceadores de carga, pueden llamar a este punto final para tomar medidas en caso de una interrupción del servicio.



3. Aceptar la autenticación de la clave API

La autenticación a través de una clave API tiene sentido si un tercero necesita llamar a la API.

Las claves de API deben pasarse mediante un encabezado HTTP personalizado, como Api-Key. Deben tener una fecha de vencimiento y las claves activas deben ser revocables para que puedan invalidarse si se ven comprometidas. Evite verificar las claves API en el código fuente (similar a las variables de entorno).



4. Usa métodos HTTP sensatos

Hay muchos métodos HTTP, pero los más importantes son:

  • POSTpara la creación de recursos
    • POST /user
  • GETPara recursos de lectura (recursos individuales y colecciones)
    • GET /user
    • GET /user/{id}
  • PATCHSe utiliza para aplicar actualizaciones parciales a los recursos.
    • PATCH /user/{id}
  • PUTSe utiliza para aplicar una actualización completa al recurso (reemplaza el recurso actual)
    • PUT /user/{id}
  • DELETESe utiliza para eliminar recursos
    • DELETE /user/{id}


5. Usa respuestas de error estandarizadas

Además de utilizar un código de estado HTTP que indique el resultado de la solicitud (éxito o error), al devolver un error, utilice siempre una respuesta de error estandarizada que contenga información más detallada sobre el problema.

El usuario de una llamada API siempre espera que se devuelva la misma estructura cada vez y puede actuar fácilmente en consecuencia.

// Request => GET /user/uiuing.com

// Response <= 404 Not Found
{
    
    
    "code": "/user/not_found",
    "message": "找不到 ID 为 uiuing.com 的用户!"
}
// Request => POST /register
{
    
    
	"name":"uiu",
	"webSite":"uiuing.com",
	"nickname":"我想养只猫"
}

// Response <= 400 Bad Request
{
    
    
    "code": "/register/password_required"",
    "message": "参数 [password] 是必须的!"
}


6. Usa PATCHen su lugarPUT

Como se mencionó anteriormente, la PATCHsolicitud debe aplicar una actualización parcial al recurso y reemplazar PUTcompletamente el recurso existente.

  • También es bastante peligroso permitir que cualquier campo se actualice sin restricciones; recomendaría
    diseñar en torno a las solicitudes porque:PATCH
  • Cuando se usa para actualizar PUTsolo una parte de los campos del recurso, aún se debe pasar todo el recurso, lo que lo hace más intensivo en la red y más propenso a errores;
  • En mi experiencia, casi no hay casos de uso en los que una actualización completa de un recurso tenga sentido en la práctica.


7. Usa la paginación

Combina todos los conjuntos de recursos devueltos y pagina las solicitudes que usan la misma estructura de respuesta. Por ejemplo page size(o similar) para controlar qué fragmentos recuperar.

// Request => GET /home/v1/get-business-list?page=1&size=10&username=uiu

// Response <= 200 OK
{
    
    
	"code":200,
	"message":"success",
    "page": 1,
    "size": 10,
    "data": [
        // resources
    ],
    "total_pages": 20,
    "has_previous_page": false,
    "has_next_page": true
}


8. Asegurar la consistencia

Sé que esto suena como si todos lo supieran, pero es difícil de hacer en la implementación real.

Una buena API es predecible, lo que significa que cuando la persona que llama usa y comprende un puerto, el otro punto final preferiblemente funciona de la misma manera. Esto es importante para la API en su conjunto y es una de las métricas clave para medir si la API está bien diseñada y es usable.

  • Use el mismo caso para campos, recursos y parámetros
  • Use nombres de recursos en plural o singular (esto no me importa, pero unificaré los nombres)
    • /users/{id},/orders/{id}o/user/{id},/order/{id}
  • Use los mismos métodos de autenticación y autorización para todos los puntos finales
  • Use los mismos encabezados HTTP en la API
    • por ejemplo, Api-Keypara pasar una clave API
  • Use el mismo código de estado HTTP según el tipo de respuesta
    • por ejemplo, usar cuando no se encuentra el recurso404
  • Utilice el mismo método HTTP para el mismo tipo de operación
    • Por ejemplo, al DELETEeliminar un recurso


9. Manejo de excepciones para puntos finales públicos

De forma predeterminada, cada puerto debe requerir autorización. La mayoría de los puertos requieren una llamada de usuario autenticado, por lo que tiene sentido que sea el valor predeterminado.

Si necesita exponer el extremo de llamada, configure este puerto explícitamente para permitir solicitudes no autorizadas.



10. API versionada

Asegúrese de crear una versión de la API y pasar la versión en cada solicitud para que los consumidores de la API no se vean afectados por ningún cambio en otra versión.

Las versiones de la API se pueden pasar mediante encabezados HTTP o parámetros de consulta/ruta. Incluso la primera versión (1.0) de la API debe tener una versión explícita.

Un ejemplo incompleto de CSDN:

  • https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=10…


11. Use códigos de estado HTTP razonables

Utilice códigos de estado HTTP tradicionales para indicar el éxito o el fracaso de una solicitud. No use demasiados y use el mismo código de estado para el mismo resultado en toda la API.

Algunos ejemplos:

  • 200éxito general
  • 201Crear para el éxito
  • 400Por mala petición del cliente
  • 401por solicitudes no autorizadas
  • 403falta de permisos
  • 404por falta de recursos
  • 429por demasiadas solicitudes
  • 5xxPor errores internos (que deben evitarse a toda costa)


12. Usa nombres que se expliquen por sí mismos

La mayoría de los puertos están orientados a los recursos y deben usar nombres que se expliquen por sí mismos sin agregar información innecesaria que pueda deducirse de otros lugares, esto también se aplica a los nombres de campo.

✅Recomendación

  • GET /user=> recuperar usuario
  • DELETE /user/{id}=> cerrar sesión usuario
  • POST /user/{id}/notifications=> Crear notificaciones para usuarios específicos
  • user.nick_name

❌ No recomendado

  • GET /getUser
  • POST /updateUser
  • POST /notification/user
  • user.NickName


13. Devolver el recurso POST creado

Se recomienda devolver el recurso creado en POST después de crear el recurso con la solicitud. Esto es importante porque el recurso creado devuelto reflejará el estado actual de la fuente de datos subyacente y contendrá información actualizada (como los ID generados).

// Request: POST /register
{
    
    
    "email": "[email protected]",
    "name": "uiu",
    "web_site":"uiuing.com"
}

// Response
{
    
    
    "id": "oVUdhmcFr0",
    "email": "[email protected]",
    "name": "uiu",
    "web_site":"uiuing.com"
}


14. Sea lo más específico posible

Como se mencionó en 12:00 , le recomiendo que sea lo más específico posible al diseñar puertos, nombrar campos y decidir qué solicitudes y respuestas aceptar. Si una PATCHsolicitud acepta solo dos campos (nombre y contraseña), no hay peligro de corromper los datos por un uso indebido.



15. Permitir recursos extendidos

Permite a la persona que llama cargar datos relacionados mediante un parámetro de consulta denominado expandir (o similar). Esto es especialmente útil para evitar la duplicación y cargar todos los datos necesarios para una operación en particular a la vez.

// Request => GET /user/T9hoBuuTL4?expand=collect&expand=collect.items

// Response <= 200 OK
{
    
    
	 "id": "oVUdhmcFr0",
	 "email": "[email protected]",
	 "name": "uiu",
	 "web_site":"uiuing.com",
	 "collect": [

		 	{
    
    
				"id": "8161E0A4-0F5C-4A02-94A5-2880645A39E0",
				"items": [
					{
    
    
						"name": "如何设计出更好的 API ?"
					},
					{
    
    
						"name": "本地存储(Local Storage) 和 会话存储(Session Storage)"
					}
				]
			},
			{
    
    
				"id": "23A7A17A-086A-4638-8EED-55E5CB580856",
				"items": [
					{
    
    
						"name": "【Jquery】 入门、快速上手、DOM/Jquery对象之间互相转换"
					}
				]
			}
		]
	]
}   




inserte la descripción de la imagen aquí

Si te es útil, no olvides dar me gusta/favorito/comentar/seguir y apoyar al bloguero.


Supongo que te gusta

Origin blog.csdn.net/qq_41103843/article/details/123328959
Recomendado
Clasificación