Apidog

Plataforma de desarrollo de API colaborativa todo en uno

Diseño de API

Documentación de API

Depuración de API

Simulación de API

Prueba automatizada de API

Introducción Completa a la Especificación JSON:API

Nikki Alessandro

Nikki Alessandro

Updated on May 19, 2025

REST (Representational State Transfer) proporciona un estilo arquitectónico fundamental para construir servicios web. Sin embargo, deja sin definir muchos aspectos del formato de solicitud y respuesta. Esta ambigüedad puede generar inconsistencias, aumentar la sobrecarga de desarrollo y una curva de aprendizaje más pronunciada para los consumidores de API. Aquí entra JSON:API, una especificación que proporciona un enfoque estandarizado y basado en convenciones para construir APIs en JSON.

Esta guía completa ofrece una inmersión profunda en la especificación JSON:API, explorando sus conceptos centrales, estructura y potentes características. Diseccionaremos sus mecanismos para obtener, crear, actualizar y eliminar recursos, gestionar relaciones, manejar errores y optimizar la transferencia de datos, equipándote con el conocimiento para diseñar y consumir APIs robustas y eficientes.

💡
¿Quieres una excelente herramienta de prueba de API que genere hermosa documentación de API?

¿Quieres una plataforma integrada y todo en uno para que tu equipo de desarrolladores trabaje en conjunto con máxima productividad?

Apidog cumple todas tus demandas y reemplaza a Postman a un precio mucho más asequible!
button

¿Por qué JSON:API? Explicación:

Antes de profundizar en las complejidades técnicas, es crucial comprender los problemas que JSON:API busca resolver. Sin una convención compartida, los desarrolladores de API a menudo dedican un tiempo considerable a debatir:

  • Estructura de la carga útil (payload): ¿Cómo deben representarse los recursos y sus atributos?
  • Representación de relaciones: ¿Cómo deben transmitirse los enlaces entre diferentes recursos?
  • Estrategias de obtención de datos: ¿Cómo pueden los clientes solicitar campos específicos, incluir recursos relacionados, ordenar, paginar y filtrar datos?
  • Informes de errores: ¿Qué formato deben seguir los mensajes de error?

JSON:API aborda esto definiendo un formato claro y consistente para solicitudes y respuestas. Esta estandarización ofrece varios beneficios clave:

  • Reducción de debates superfluos (Bikeshedding): Al proporcionar respuestas a preguntas comunes de diseño, JSON:API permite a los equipos centrarse en la lógica de negocio central de sus aplicaciones en lugar de debatir minucias del diseño de API.
  • Mejora de la productividad: Los formatos estandarizados significan menos código personalizado tanto para los productores como para los consumidores de API. Se pueden desarrollar bibliotecas cliente para manejar gran parte del código repetitivo para interactuar con cualquier servicio compatible con JSON:API.
  • Mayor capacidad de descubrimiento y usabilidad: Las estructuras de enlace consistentes y la clara delimitación de recursos y relaciones hacen que las APIs sean más fáciles de entender y navegar.
  • Transferencia de datos optimizada: Características como los conjuntos de campos dispersos (sparse fieldsets) y los documentos compuestos permiten a los clientes solicitar solo los datos que necesitan, minimizando el tamaño de la carga útil y reduciendo el número de solicitudes HTTP.
  • Caché más sencilla: La especificación promueve el uso de mecanismos estándar de caché HTTP.
  • Independiente del lenguaje: Al basarse en JSON, es inherentemente independiente del lenguaje, lo que facilita una amplia adopción en diversas pilas tecnológicas.

Conceptos centrales: Los bloques de construcción de un documento JSON:API

En su esencia, JSON:API gira en torno al concepto de recursos. Un recurso es un registro individual de un tipo particular, como un "artículo", un "usuario" o un "producto". Cada documento JSON:API, ya sea una solicitud o una respuesta, se adhiere a una estructura específica.

La estructura del documento: Miembros de nivel superior

Un documento JSON:API es un objeto JSON que debe contener al menos uno de los siguientes miembros de nivel superior:

  • data: Los "datos primarios" del documento. Esto puede ser:
  • Un solo objeto de recurso (por ejemplo, al obtener un artículo específico).
  • Un array de objetos de recurso (por ejemplo, al obtener una colección de artículos).
  • Un solo objeto identificador de recurso (para representar una relación uno a uno).
  • Un array de objetos identificadores de recurso (para representar una relación uno a muchos).
  • null (por ejemplo, cuando una relación uno a uno está vacía, o una solicitud de un solo recurso que no existe).
  • Un array vacío [] (por ejemplo, cuando una relación uno a muchos está vacía, o una solicitud de una colección no arroja resultados).
  • errors: Un array de objetos de error que proporcionan detalles sobre los errores de procesamiento. El miembro data no debe estar presente si errors está presente.
  • meta: Un objeto meta que contiene meta-información no estándar que no encaja en el resto de la especificación.

Además, un documento puede contener estos miembros de nivel superior:

  • jsonapi: Un objeto que describe la implementación del servidor. Puede incluir version (la versión más alta de JSON:API soportada), ext (un array de URIs para extensiones aplicadas) y profile (un array de URIs para perfiles aplicados).
  • links: Un objeto links relacionado con los datos primarios. Esto puede incluir self-links, links de recursos relacionados y links de paginación.
  • included: Un array de objetos de recurso que están relacionados con los datos primarios y/o entre sí. Esto se utiliza para "documentos compuestos" para reducir el número de solicitudes HTTP cargando recursos relacionados de forma lateral (sideloading).

Objetos de recurso: Representando tus datos

Un objeto de recurso es la piedra angular de JSON:API y debe contener:

  • type: Un string que identifica el tipo del recurso (por ejemplo, "articles", "users"). Esto ayuda a nombrar los recursos y evita colisiones de ID entre diferentes tipos.
  • id: Un string que identifica de forma única el recurso dentro de su tipo.

Un objeto de recurso puede también contener:

  • attributes: Un objeto attributes que contiene datos específicos del recurso. Las claves en el objeto attributes representan las propiedades del recurso (por ejemplo, "title", "body" para un artículo). Las relaciones no deben representarse en el objeto attributes.
  • relationships: Un objeto relationships que describe las conexiones entre el recurso y otros recursos.
  • links: Un objeto links que contiene enlaces relacionados con el recurso, como un enlace self que apunta a la URL canónica del recurso.
  • meta: Un objeto meta que contiene meta-información no estándar sobre el recurso.

Ejemplo de un objeto de recurso:JSON

{
  "type": "articles",
  "id": "1",
  "attributes": {
    "title": "JSON:API Revelado",
    "body": "Una inmersión profunda en la especificación...",
    "created_at": "2025-05-15T10:00:00Z",
    "updated_at": "2025-05-16T14:30:00Z"
  },
  "relationships": {
    "author": {
      "links": {
        "self": "/articles/1/relationships/author",
        "related": "/articles/1/author"
      },
      "data": { "type": "users", "id": "42" }
    },
    "comments": {
      "links": {
        "self": "/articles/1/relationships/comments",
        "related": "/articles/1/comments"
      },
      "data": [
        { "type": "comments", "id": "5" },
        { "type": "comments", "id": "12" }
      ]
    }
  },
  "links": {
    "self": "/articles/1"
  }
}

Objetos identificadores de recurso

Los objetos identificadores de recurso son representaciones mínimas de un recurso, que contienen solo type e id. Se utilizan dentro de los objetos de relación para enlazar a otros recursos sin incrustar el objeto de recurso completo.

Ejemplo de un objeto identificador de recurso:JSON

{ "type": "users", "id": "42" }

Los objetos links proporcionan URLs para navegar por la API. Los miembros de enlace comunes incluyen:

  • self: Un enlace que representa el recurso o documento en sí.
  • related: Un enlace a un recurso o colección relacionada. A menudo se utiliza en relaciones para obtener los datos relacionados reales.
  • Enlaces de paginación: first, last, prev, next para navegar por colecciones paginadas.

Un enlace puede representarse como:

  • Un string simple que contiene la URL.
  • Un objeto de enlace, que debe contener un href (URL string) y puede incluir opcionalmente rel (tipo de relación), describedby (enlace a un documento de descripción), title, type (tipo de medio del destino), hreflang y un objeto meta.

Ejemplo de un objeto Links (dentro de una relación):JSON

"links": {
  "self": "http://example.com/articles/1/relationships/author",
  "related": "http://example.com/articles/1/author"
}

Objetos Meta

Los objetos meta permiten la inclusión de meta-información no estándar. Pueden ser pares clave-valor arbitrarios. Por ejemplo, un objeto meta podría incluir información de derechos de autor o marcas de tiempo relacionadas con los datos.

Ejemplo de un objeto Meta:JSON

"meta": {
  "copyright": "Copyright 2025 Example Corp.",
  "authors": ["John Doe"]
}

Negociación de contenido: Hablando el lenguaje correcto

JSON:API define su propio tipo de medio: application/vnd.api+json.

  • Encabezado Accept: Los clientes deben enviar este encabezado con el tipo de medio application/vnd.api+json para indicar que esperan una respuesta compatible con JSON:API. Si un servidor no puede satisfacer ninguno de los tipos de medio en el encabezado Accept, debe responder con un estado 406 Not Acceptable.
  • Encabezado Content-Type: Los clientes y servidores deben usar este encabezado con el tipo de medio application/vnd.api+json para todas las solicitudes y respuestas que contengan un documento JSON:API en su cuerpo. Si una solicitud especifica un Content-Type diferente a application/vnd.api+json (u otros tipos de medio registrados que el servidor admita) y contiene un cuerpo, el servidor debe responder con un estado 415 Unsupported Media Type. Si una solicitud especifica Content-Type: application/vnd.api+json pero el cuerpo no es un documento JSON:API válido, el servidor debe responder con 400 Bad Request.

Los servidores pueden admitir otros tipos de medio junto con application/vnd.api+json a través de la negociación de contenido estándar.

Obtención de datos: Recuperando recursos y colecciones

JSON:API proporciona mecanismos robustos para que los clientes recuperen datos precisamente según sea necesario.

Obteniendo recursos individuales

Para obtener un solo recurso, un cliente envía una solicitud GET a un endpoint que representa ese recurso.

Solicitud:

GET /articles/1

Accept: application/vnd.api+json

Respuesta exitosa (200 OK):JSON

{
  "links": {
    "self": "/articles/1"
  },
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "¡JSON:API Mola!"
    }
    // ... otros atributos y relaciones
  }
}

Si el recurso no existe, el servidor debería devolver un 404 Not Found. Si se obtiene un enlace de recurso relacionado uno a uno y la relación está vacía, los datos primarios serán null.

Obteniendo colecciones de recursos

Para obtener una colección de recursos, un cliente envía una solicitud GET a un endpoint que representa esa colección.

Solicitud:

GET /articles

Accept: application/vnd.api+json

Respuesta exitosa (200 OK):JSON

{
  "links": {
    "self": "/articles",
    "next": "/articles?page[offset]=10",
    "last": "/articles?page[offset]=50"
  },
  "data": [
    {
      "type": "articles",
      "id": "1",
      "attributes": { "title": "Artículo 1" }
      // ...
    },
    {
      "type": "articles",
      "id": "2",
      "attributes": { "title": "Artículo 2" }
      // ...
    }
    // ... más artículos
  ]
}

Si la colección está vacía, el miembro data será un array vacío [].

Relaciones: Conectando recursos

Las relaciones son una parte fundamental de la mayoría de los modelos de datos. JSON:API proporciona una forma clara de definirlas e interactuar con ellas.

Representando relaciones

Las relaciones se definen dentro del objeto relationships de un recurso. Cada entrada en el objeto relationships representa una relación distinta (por ejemplo, "author", "comments").

Un objeto de relación debe contener al menos uno de:

  • links: Contiene enlaces self y related.
  • El enlace self (URL de la relación) permite la manipulación de la relación en sí (por ejemplo, agregar/eliminar elementos en una relación uno a muchos). Cuando se obtiene, devuelve objetos identificadores de recurso para los recursos relacionados.
  • El enlace related (URL del recurso relacionado) permite obtener directamente los objetos de recurso relacionados.
  • data: Contiene la vinculación de recursos (objetos identificadores de recurso).
  • Para una relación uno a uno: un solo objeto identificador de recurso o null.
  • Para una relación uno a muchos: un array de objetos identificadores de recurso o un array vacío [].
  • meta: Un objeto meta para información no estándar sobre la relación.

Ejemplo de relaciones "author" (uno a uno) y "comments" (uno a muchos):JSON

"relationships": {
  "author": {
    "links": {
      "self": "/articles/1/relationships/author",
      "related": "/articles/1/author"
    },
    "data": { "type": "users", "id": "42" }
  },
  "comments": {
    "links": {
      "self": "/articles/1/relationships/comments",
      "related": "/articles/1/comments"
    },
    "data": [
      { "type": "comments", "id": "5" },
      { "type": "comments", "id": "12" }
    ]
  }
}

Obteniendo relaciones

Los clientes pueden obtener información sobre una relación en sí o sobre los recursos relacionados utilizando los enlaces proporcionados.

Obteniendo la vinculación de la relación (enlace self):

GET /articles/1/relationships/comments

Accept: application/vnd.api+json

Esto devuelve una colección de objetos identificadores de recurso para los comentarios relacionados con el artículo "1".

Obteniendo recursos relacionados (enlace related):

GET /articles/1/comments

Accept: application/vnd.api+json

Esto devuelve una colección de objetos de recurso de comentario completos relacionados con el artículo "1".

Optimizando la recuperación de datos

JSON:API ofrece varias características para optimizar la forma en que se recuperan los datos, minimizando el ancho de banda y mejorando el rendimiento del lado del cliente.

Documentos compuestos: Reduciendo solicitudes HTTP con include

Para evitar múltiples viajes de ida y vuelta al servidor para obtener recursos relacionados, JSON:API permite a los clientes solicitar que los recursos relacionados se incluyan en la respuesta primaria utilizando el parámetro de consulta include. El servidor cargará lateralmente estos recursos en el array included de nivel superior.

Solicitud para obtener un artículo e incluir su autor y comentarios:

GET /articles/1?include=author,comments

Accept: application/vnd.api+json

Respuesta (200 OK):JSON

{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": { "title": "..." },
    "relationships": {
      "author": {
        "data": { "type": "users", "id": "42" }
      },
      "comments": {
        "data": [
          { "type": "comments", "id": "5" },
          { "type": "comments", "id": "12" }
        ]
      }
    }
  },
  "included": [
    {
      "type": "users",
      "id": "42",
      "attributes": { "name": "John Doe" }
    },
    {
      "type": "comments",
      "id": "5",
      "attributes": { "body": "¡Excelente artículo!" }
    },
    {
      "type": "comments",
      "id": "12",
      "attributes": { "body": "Muy informativo." }
    }
  ]
}
  • El parámetro include toma una lista separada por comas de rutas de relación.
  • Las relaciones anidadas se pueden incluir usando notación de puntos (por ejemplo, include=comments.author).
  • Si un endpoint no admite include, debe devolver 400 Bad Request.
  • El servidor no debe incluir recursos no solicitados en la sección included.

Conjuntos de campos dispersos (Sparse Fieldsets): Obteniendo solo los campos necesarios

Los clientes pueden solicitar que solo se devuelvan campos específicos (atributos y relaciones) para recursos de un tipo dado utilizando el parámetro de consulta fields[TYPE]. Esto reduce el tamaño de la carga útil.

Solicitud para obtener artículos, pero solo su título y la relación con el autor:

GET /articles?fields[articles]=title,author

Accept: application/vnd.api+json

Respuesta (200 OK):JSON

{
  "data": [
    {
      "type": "articles",
      "id": "1",
      "attributes": {
        "title": "Artículo 1"
      },
      "relationships": {
        "author": {
          "data": { "type": "users", "id": "42" }
        }
      }
    }
    // ... otros artículos con solo título y autor
  ]
}
  • Los campos id y type siempre se incluyen.
  • Si un cliente solicita un campo que no existe, el servidor debe ignorarlo.
  • Si un cliente solicita solo campos que son relaciones, el miembro attributes puede omitirse.

Ordenación (Sorting)

Los clientes pueden solicitar que los datos primarios se ordenen utilizando el parámetro de consulta sort.

Solicitud para obtener artículos ordenados por fecha de creación (descendente) y luego por título (ascendente):

GET /articles?sort=-created_at,title

Accept: application/vnd.api+json

  • Un guion inicial (-) indica orden descendente; de lo contrario, es ascendente.
  • El servidor define qué atributos se pueden usar para la ordenación. Las solicitudes para ordenar por atributos no admitidos deberían resultar en un 400 Bad Request.

Paginación

JSON:API admite varias estrategias de paginación. La especificación define cómo deben aparecer los enlaces de paginación (first, prev, next, last) en el objeto links de nivel superior. La estrategia de paginación real (por ejemplo, basada en página, basada en offset, basada en cursor) la determina el servidor utilizando parámetros de consulta como page[number], page[size], page[offset], page[limit] o page[cursor].

Ejemplo de enlaces de paginación basados en página:JSON

"links": {
  "self": "/articles?page[number]=2&page[size]=10",
  "first": "/articles?page[number]=1&page[size]=10",
  "prev": "/articles?page[number]=1&page[size]=10",
  "next": "/articles?page[number]=3&page[size]=10",
  "last": "/articles?page[number]=5&page[size]=10"
}

Los clientes deben usar estos enlaces proporcionados en lugar de construir sus propias URLs de paginación.

Filtrado (Filtering)

La especificación reserva el parámetro de consulta filter para filtrar datos. Sin embargo, no exige una estrategia de filtrado específica. Los servidores pueden implementar cualquier estrategia, como filter[attribute]=value o un filtrado basado en expresiones más complejo.

Ejemplo (recomendado por JSON:API, pero no obligatorio):

GET /comments?filter[post]=1 (Obtener comentarios para la publicación con ID 1)

GET /comments?filter[post]=1,2&filter[author]=12 (Obtener comentarios para las publicaciones 1 o 2, por el autor 12)

Los clientes deben consultar la documentación de la API para comprender sus capacidades de filtrado específicas.

Modificando datos: Creando, actualizando y eliminando recursos

JSON:API define protocolos claros para las operaciones de manipulación de datos.

Creando recursos

Para crear un recurso, un cliente envía una solicitud POST a una URL que representa una colección de recursos. El cuerpo de la solicitud debe contener un único objeto de recurso con type y, opcionalmente, attributes y relationships. El cliente no debe proporcionar un id para el nuevo recurso (a menos que se admitan y habiliten los ID generados por el cliente).

Solicitud:

POST /articles

Accept: application/vnd.api+json

Content-Type: application/vnd.api+jsonJSON

{
  "data": {
    "type": "articles",
    "attributes": {
      "title": "Título del Nuevo Artículo",
      "body": "Contenido del nuevo artículo."
    },
    "relationships": {
      "author": {
        "data": { "type": "users", "id": "42" }
      }
    }
  }
}

Respuestas exitosas:

  • 201 Created: Si el recurso se creó correctamente. La respuesta debe incluir un encabezado Location que identifique la URL del recurso recién creado. El cuerpo de la respuesta debería incluir el recurso recién creado, incluido su id asignado por el servidor.
  • 202 Accepted: Si la solicitud de creación ha sido aceptada para su procesamiento, pero el procesamiento aún no está completo (por ejemplo, para operaciones asíncronas). La respuesta puede incluir un enlace para monitorear el estado.
  • 204 No Content: Si el recurso se creó correctamente, pero el servidor decide no devolver la representación del recurso en el cuerpo de la respuesta. El encabezado Location sigue siendo obligatorio.

Si se intenta crear un recurso con un ID generado por el cliente que ya existe, y el servidor no admite la actualización a través de POST, debe devolver 409 Conflict.

Actualizando recursos

Los recursos se actualizan utilizando el método HTTP PATCH. La solicitud debe incluir el id del recurso a actualizar. El cuerpo de la solicitud contiene un objeto de recurso con type, id y los attributes y/o relationships a actualizar.

Solicitud para actualizar el título de un artículo y una de sus relaciones:

PATCH /articles/1

Accept: application/vnd.api+json

Content-Type: application/vnd.api+jsonJSON{ "data": { "type": "articles", "id": "1", "attributes": { "title": "Título del Artículo Actualizado" }, "relationships": { "tags": { "data": [ { "type": "tags", "id": "3" }, { "type": "tags", "id": "4" } ] } } } }

Puntos clave para las actualizaciones:

  • Actualizaciones parciales: Las solicitudes PATCH deberían ser parciales. Solo se deben actualizar los campos presentes en la solicitud. Los campos no incluidos deben permanecer sin cambios.
  • Actualizando relaciones:
  • Uno a uno: Proporcionar un objeto identificador de recurso o null en los data de la relación.
  • Uno a muchos: Proporcionar un array de objetos identificadores de recurso. Esto reemplaza completamente los miembros de la relación existentes. Para agregar o eliminar miembros sin reemplazar todo el conjunto, se deben usar endpoints de relación dedicados (/articles/1/relationships/tags) con POST (para agregar), DELETE (para eliminar) o PATCH (para reemplazar todos).
  • El servidor no debe actualizar atributos o relaciones que no se especifiquen en la solicitud.

Respuestas exitosas:

  • 200 OK: Si la actualización fue exitosa y el servidor devuelve una representación del recurso actualizado.
  • 202 Accepted: Si la solicitud de actualización ha sido aceptada para su procesamiento, pero aún no está completa.
  • 204 No Content: Si la actualización fue exitosa, pero el servidor decide no devolver una representación.

Si el recurso a actualizar no existe, el servidor debe devolver 404 Not Found.

Actualizando relaciones directamente

JSON:API proporciona formas específicas para gestionar relaciones sin afectar los atributos del recurso primario.

  • Actualizando una relación uno a uno:PATCH /articles/1/relationships/authorContent-Type: application/vnd.api+jsonJSON
{
  "data": { "type": "users", "id": "24" } // Asignar nuevo autor o null para borrar
}
  • Actualizando una relación uno a muchos (reemplazo completo):PATCH /articles/1/relationships/commentsContent-Type: application/vnd.api+jsonJSON
{
  "data": [
    { "type": "comments", "id": "101" },
    { "type": "comments", "id": "102" }
  ]
}
  • Agregando a una relación uno a muchos:POST /articles/1/relationships/commentsContent-Type: application/vnd.api+jsonJSON
{
  "data": [
    { "type": "comments", "id": "103" }
  ]
}
  • Eliminando de una relación uno a muchos:DELETE /articles/1/relationships/commentsContent-Type: application/vnd.api+jsonJSON
{
  "data": [
    { "type": "comments", "id": "5" }
  ]
}

Las actualizaciones de relaciones exitosas suelen devolver 200 OK o 204 No Content.

Eliminando recursos

Para eliminar un recurso, un cliente envía una solicitud DELETE al endpoint del recurso.

Solicitud:

DELETE /articles/1

Accept: application/vnd.api+json

Respuesta exitosa:

  • 204 No Content: Si la eliminación fue exitosa y no se devuelve cuerpo de respuesta.
  • 200 OK: Si el servidor devuelve meta-información sobre la eliminación.
  • 202 Accepted: Si la solicitud de eliminación ha sido aceptada para su procesamiento.

Si el recurso no existe, el servidor debería devolver 404 Not Found. La especificación no dicta cómo deben manejarse los recursos o relaciones relacionadas al eliminar (por ejemplo, eliminaciones en cascada); este es un detalle de implementación.

Manejo de errores

Cuando ocurre un error, los servidores deben usar códigos de estado HTTP apropiados (4xx para errores del cliente, 5xx para errores del servidor). El cuerpo de la respuesta debería contener un documento de error JSON:API.

Un documento de error incluye un miembro errors de nivel superior, que es un array de objetos de error. Cada objeto de error puede contener:

  • id: Un identificador único para esta ocurrencia particular del problema.
  • links: Un objeto links que contiene:
  • about: Un enlace que conduce a más1 detalles sobre esta ocurrencia particular del problema.
  • type: Un enlace que identifica el tipo de error del que esta ocurrencia particular es una instancia.
  • status: El código de estado HTTP aplicable a este problema, expresado como un string.
  • code: Un código de error específico de la aplicación, expresado como un2 string.
  • title: Un resumen corto y legible por humanos del problema.3
  • detail: Una explicación legible por humanos específica para esta ocurrencia del problema.
  • source: Un objeto que contiene referencias al origen del error en el documento de solicitud:4
  • pointer: Un JSON Pointer [RFC6901] a la entidad asociada en el documento de solicitud.
  • parameter: Un string que indica qué parámetro de consulta URI causó el error.
  • header:5 Un string que indica el nombre de un único encabezado de solicitud que causó el error.
  • meta: Un objeto meta que contiene meta-información no estándar sobre el error.

Ejemplo de respuesta de error (422 Unprocessable Entity):JSON

{
  "errors": [
    {
      "status": "422",
      "source": { "pointer": "/data/attributes/email" },
      "title": "Atributo Inválido",
      "detail": "La dirección de correo electrónico no es válida."
    },
    {
      "status": "422",
      "source": { "pointer": "/data/relationships/author" },
      "title": "Valor de Relación Inválido",
      "detail": "El autor con ID '999' no existe."
    }
  ]
}

Consideraciones del lado del servidor y mejores prácticas

Si bien la especificación central es completa, JSON:API también proporciona recomendaciones para aspectos como el diseño de URL y la nomenclatura de miembros.

Diseño de URL

  • Usar sustantivos plurales para colecciones de recursos (por ejemplo, /articles).
  • Usar /articles/{id} para recursos individuales.
  • Usar /articles/{id}/relationships/{relationshipName} para self-links de relaciones.
  • Usar /articles/{id}/{relationshipName} para enlaces de recursos relacionados.

Nomenclatura de miembros

  • Los nombres de los miembros (claves) deberían estar en camel-case (por ejemplo, firstName) o usar guiones/guiones bajos como separadores de palabras (por ejemplo, first-name o first_name). La consistencia dentro de una API es clave. La especificación misma utiliza kebab-case para sus propios parámetros de consulta (por ejemplo, page[number]).
  • Los nombres de los miembros deberían contener solo caracteres alfanuméricos ASCII, guiones y guiones bajos.

Extendiendo la especificación: Extensiones y perfiles

JSON:API está diseñado para ser extensible para satisfacer necesidades cambiantes y casos de uso específicos.

Extensiones

Las extensiones pueden introducir nueva funcionalidad no cubierta por la especificación base. Un ejemplo es la extensión "Atomic Operations", que permite realizar múltiples operaciones (crear, actualizar, eliminar) en una única solicitud atómica. Tanto el cliente como el servidor deben comprender una extensión para que pueda ser utilizada. Si un servidor recibe una solicitud con una extensión no admitida, debe responder con un error apropiado.

Perfiles

Los perfiles definen un conjunto de convenciones sobre la especificación base para un caso de uso particular (por ejemplo, una forma específica de manejar marcas de tiempo o un conjunto común de atributos meta). A diferencia de las extensiones, los perfiles pueden ignorarse de forma segura si una de las partes no los comprende. Están destinados a promover la interoperabilidad para patrones comunes sin requerir cambios en la especificación central o exigir soporte universal.

Los servidores pueden anunciar las extensiones y perfiles admitidos en el objeto jsonapi de nivel superior. Esto permite a los clientes descubrir estas capacidades y adaptar sus solicitudes en consecuencia.

El futuro de JSON:API

JSON:API continúa evolucionando, impulsado por la contribución de la comunidad y la necesidad de abordar los desafíos emergentes del diseño de API. Su enfoque en la convención sobre la configuración, la eficiencia y la experiencia del desarrollador ha consolidado su lugar como un estándar líder para construir APIs modernas. Al adoptar JSON:API, los equipos de desarrollo pueden reducir significativamente la ambigüedad, mejorar la interoperabilidad y acelerar el ritmo de desarrollo y consumo de APIs.

Esta exploración detallada cubre la gran mayoría de la especificación JSON:API. Al comprender e implementar estos principios, los desarrolladores pueden crear APIs que no solo sean funcionales, sino también limpias, consistentes y un placer trabajar con ellas, fomentando en última instancia un ecosistema de API más productivo y colaborativo.