logo

Extra Block Types (EBT) - Nueva experiencia con Layout Builder❗

Extra Block Types (EBT): tipos de bloques con estilo y personalizables: Presentaciones de diapositivas, Pestañas, Tarjetas, Acordeones y muchos más. Configuraciones integradas para fondo, DOM Box y plugins de JavaScript. Experimenta hoy el futuro de la construcción de diseños.

Módulos de demostración EBT Descargar módulos EBT

❗Extra Paragraph Types (EPT) - Nueva experiencia con Paragraphs

Extra Paragraph Types (EPT): conjunto de módulos basado en párrafos de forma análoga.

Módulos de demostración EPT Descargar módulos EPT

Scroll
18/05/2025, by Ivan

Las colecciones son listados de recursos. En un sitio desacoplado (decoupled), se utilizan para crear cosas como una lista de “Nuevo Contenido” o una sección de “Mi contenido” en el lado del cliente.

Sin embargo, cuando realizas una solicitud sin filtros a un endpoint de colección como /jsonapi/node/article, simplemente obtendrás todos los artículos a los que tienes permiso de ver.

Sin filtros, no puedes obtener solo tus artículos o solo los artículos sobre llamas.

Esta guía te enseñará cómo construir filtros como un profesional.

Inicio Rápido

El filtro más simple y común es un filtro clave-valor:

?filter[field_name]=value&filter[field_other]=value

Esto coincide con todos los recursos donde “field_name” es igual a “value” y “field_other” es igual a “value”.

¡Para todo lo demás, sigue leyendo!

Resumen


El módulo JSON:API tiene unas de las funcionalidades de filtrado más potentes y ricas en características. Todo ese poder viene acompañado de cierta curva de aprendizaje.

Al final de este artículo, podrás hacer consultas complejas y entender problemas como “¿cómo obtengo una lista de los artículos de un autor sobre llamas o sobre el miembro más rápido del reino animal, el halcón peregrino?”

Comenzaremos desde lo más básico. Luego mostraremos algunos atajos que hacen los filtros más rápidos y menos verbosos. Finalmente, veremos varios ejemplos de filtros tomados del mundo real.

Si ya has usado Drupal, probablemente hayas usado el módulo Views para este tipo de cosas. A diferencia del módulo REST que viene en el núcleo de Drupal, JSON:API no exporta resultados de Views. Las colecciones son el reemplazo “API-First” de JSON:API para los “REST displays” exportados en Views.

Construyendo Filtros


Los bloques fundamentales de los filtros en JSON:API son las condiciones y los grupos. Las condiciones afirman que algo es cierto, y los grupos te permiten componer esas afirmaciones en conjuntos lógicos para hacer grupos de condiciones más grandes. Estos conjuntos pueden anidarse para crear consultas muy precisas. Puedes pensar en estos conjuntos anidados como un árbol:

Representación convencional:

a( b() && c( d() || e() ) )

Representación en árbol:

   a
  / \
 b   c
     / \
    d   e

En ambas representaciones:

“d” y “e” son miembros de “c” en un grupo OR.
“b” y “c” son miembros de “a” en un grupo AND.

¿Qué contiene una condición?

Una condición tiene 3 partes principales: una ruta (path), un operador y un valor.

  • Una ‘ruta’ identifica un campo en un recurso
  • Un ‘operador’ es un método de comparación
  • Un ‘valor’ es lo que se compara

En pseudo-código, una condición se ve así:

($field !== 'space')

Dónde:

  1. $field es el campo del recurso identificado por su ‘ruta’
  2. el ‘operador’ es !==
  3. el ‘valor’ es la cadena 'space'

En el módulo JSON:API, no podemos hacer que se vea tan bonito porque necesitamos que funcione dentro de una cadena de consulta en la URL. Para eso, representamos cada condición como pares clave/valor.

Si filtramos por el primer nombre de un usuario, una condición sería así:

?filter[a-label][condition][path]=field_first_name
&filter[a-label][condition][operator]=%3D  <- símbolo “=” codificado
&filter[a-label][condition][value]=Janis

Nota que colocamos una etiqueta dentro del primer conjunto de corchetes. Podría ser b-label, mi_super_etiqueta o incluso un número como 666. El punto es que todas las condiciones o grupos deben tener un identificador.

¿Y si hay muchas personas llamadas Janis?

Agregamos otro filtro para obtener solo las Janis con apellido que empieza por “J”:

?filter[first-name-filter][condition][path]=field_first_name
&filter[first-name-filter][condition][operator]=%3D
&filter[first-name-filter][condition][value]=Janis

&filter[last-name-filter][condition][path]=field_last_name
&filter[last-name-filter][condition][operator]=STARTS_WITH
&filter[last-name-filter][condition][value]=J

Hay muchos más operadores de filtro que solo = y STARTS_WITH. Aquí tienes la lista completa según el código de JSON:API:

\Drupal\jsonapi\Query\EntityCondition::$allowedOperators = [
  '=', '<>',
  '>', '>=', '<', '<=',
  'STARTS_WITH', 'CONTAINS', 'ENDS_WITH',
  'IN', 'NOT IN',
  'BETWEEN', 'NOT BETWEEN',
  'IS NULL', 'IS NOT NULL',
];

Los operadores de símbolo deben estar codificados para URL. Puedes obtener la codificación correcta con la función urlencode() de PHP.

Grupos de Condiciones


Ahora sabemos construir condiciones, pero aún no sabemos cómo construir grupos de condiciones. ¿Cómo construimos un árbol como el anterior?

Para eso necesitamos un “grupo”. Un grupo es un conjunto de condiciones unidas por una “conjunción”. Todos los grupos tienen conjunciones y una conjunción es AND o OR.

Supón que queremos encontrar todos los usuarios cuyo apellido empieza con “J” y cuyo nombre es “Janis” o “Joan”.

?filter[rock-group][group][conjunction]=OR

&filter[janis-filter][condition][path]=field_first_name
&filter[janis-filter][condition][operator]=%3D
&filter[janis-filter][condition][value]=Janis
&filter[janis-filter][condition][memberOf]=rock-group

&filter[joan-filter][condition][path]=field_first_name
&filter[joan-filter][condition][operator]=%3D
&filter[joan-filter][condition][value]=Joan
&filter[joan-filter][condition][memberOf]=rock-group

&filter[last-name-filter][condition][path]=field_last_name
&filter[last-name-filter][condition][operator]=STARTS_WITH
&filter[last-name-filter][condition][value]=J

Puedes anidar estos grupos tanto como quieras.

Rutas (Paths)

Las rutas permiten filtrar basándose en valores de relaciones. Por ejemplo:

?filter[career][condition][path]=field_career.name
&filter[career][condition][operator]=%3D
&filter[career][condition][value]=Rockstar

Las rutas usan la notación de puntos para recorrer relaciones (relacion.campo).

Atajos


Cuando el operador es =, no es necesario incluirlo; se asume por defecto. Así:

?filter[field_first_name]=Janis

Filtros y Control de Acceso


No confundas los filtros con el control de acceso. Siempre realiza los chequeos de acceso en el backend.

Para mejorar el rendimiento, filtra lo que los usuarios no podrán ver. Ejemplo, para usuarios que no pueden ver contenido no publicado, usa:

?filter[status][value]=1

JSON:API no devuelve datos de recursos a los que el usuario no tiene acceso.

Ejemplos de Filtros


1. Obtener solo nodos publicados

SHORT
filter[status][value]=1

NORMAL
filter[status-filter][condition][path]=status
filter[status-filter][condition][value]=1

2. Obtener nodos por valor de referencia de entidad

SHORT
filter[uid.id][value]=BB09E2CD-9487-44BC-B219-3DC03D6820CD

NORMAL
filter[author-filter][condition][path]=uid.id
filter[author-filter][condition][value]=BB09E2CD-9487-44BC-B219-3DC03D6820CD
SHORT
filter[field_tags.meta.drupal_internal__target_id]=1

NORMAL
filter[name-filter][condition][path]=field_tags.meta.drupal_internal__target_id
filter[name-filter][condition][value]=1

3. Filtros anidados: nodos creados por el usuario admin

SHORT
filter[uid.name][value]=admin

NORMAL
filter[name-filter][condition][path]=uid.name
filter[name-filter][condition][value]=admin

4. Filtrar con arrays: nodos creados por usuarios [admin, john]

NORMAL
filter[name-filter][condition][path]=uid.name
filter[name-filter][condition][operator]=IN
filter[name-filter][condition][value][1]=admin
filter[name-filter][condition][value][2]=john

5. Agrupando filtros: nodos publicados y creados por admin

filter[and-group][group][conjunction]=AND
filter[name-filter][condition][path]=uid.name
filter[name-filter][condition][value]=admin
filter[name-filter][condition][memberOf]=and-group
filter[status-filter][condition][path]=status
filter[status-filter][condition][value]=1
filter[status-filter][condition][memberOf]=and-group

6. Agrupando grupos de filtros: nodos promovidos o destacados y creados por admin

# Crear un grupo AND y un grupo OR
filter[and-group][group][conjunction]=AND
filter[or-group][group][conjunction]=OR

# Poner el grupo OR dentro del grupo AND
filter[or-group][group][memberOf]=and-group

# Filtro para admin en grupo AND
filter[admin-filter][condition][path]=uid.name
filter[admin-filter][condition][value]=admin
filter[admin-filter][condition][memberOf]=and-group

# Filtro para sticky en grupo OR
filter[sticky-filter][condition][path]=sticky
filter[sticky-filter][condition][value]=1
filter[sticky-filter][condition][memberOf]=or-group

# Filtro para promote en grupo OR
filter[promote-filter][condition][path]=promote
filter[promote-filter][condition][value]=1
filter[promote-filter][condition][memberOf]=or-group

7. Filtrar nodos donde el 'title' CONTIENE "Foo"

SHORT
filter[title][operator]=CONTAINS&filter[title][value]=Foo

NORMAL
filter[title-filter][condition][path]=title
filter[title-filter][condition][operator]=CONTAINS
filter[title-filter][condition][value]=Foo

8. Filtrar por campos complejos no estándar (por ejemplo, addressfield)

FILTRAR POR LOCALIDAD
filter[field_address][condition][path]=field_address.locality
filter[field_address][condition][value]=Mordor

FILTRAR POR DIRECCIÓN
filter[address][condition][path]=field_address.address_line1
filter[address][condition][value]=Rings Street

9. Filtrar por valores de términos de taxonomía (ejemplo: tags)

filter[taxonomy_term--tags][condition][path]=field_tags.name
filter[taxonomy_term--tags][condition][operator]=IN
filter[taxonomy_term--tags][condition][value][]=tagname

10. Filtrar por fecha (solo fecha, sin hora)

filter[datefilter][condition][path]=field_test_date
filter[datefilter][condition][operator]=%3D
filter[datefilter][condition][value]=2019-06-27

Ejemplo para campo fecha/hora:

filter[datefilter][condition][path]=field_test_date
filter[datefilter][condition][operator]=%3D
filter[datefilter][condition][value]=2019-06-27T16%3A00%3A00

Para timestamp (como created o changed):

filter[recent][condition][path]=created
filter[recent][condition][operator]=%3D
filter[recent][condition][value]=1591627496

11. Filtrar campos de arrays vacíos

Por ejemplo, para un campo de tipo Checkboxes sin valor seleccionado (cuando está vacío, JSON API retorna un array vacío []):

filter[my-filter][condition][path]=my_field
filter[my-filter][condition][operator]=IS NULL

Artículo de la Documentación de Drupal.