Búsqueda de sitios web

typescript - Manipular consultas antes de enviarlas a GraphQL


Estamos usando apollo-client y apollo-server-express para obtener datos de una API de traducción simple.

Ese es el esquema actual:

type Query {
    translations(language: String!, key: String!): Translation!
}

type Translation {
    key: String!
    value: String!
}

Y el resolutor:

export default {
  Query: {
    translations (obj, args, context, info) {
      return fetchApi('/api/v1/translation', {
        method: 'POST',
        body: JSON.stringify(args)
      })
    }
  }
}

En la aplicación frontend tenemos un componente de React que recibe la clave de traducción dentro de las props y luego ejecuta la consulta contra el servidor GraphQL:

const translationQuery = gql`
query GetTranslations($language: String!, $key: String!) {
  translations(language: $language, key: $key) {
    value
    key
  }
}`

En este momento, esto conduce a llamadas de GraphQL para CADA traducción. Lo que necesitamos es acumular todas las traducciones y luego realizar UNA consulta de GraphQL. Básicamente, nos gustaría usar una consulta que acepte una lista de claves pero aún así usar un componente de traducción dedicado:

type Query {
    translations(language: String!, keys: [String!]!): Translation!
}

type Translation {
    key: String!
    value: String!
}

¿Hay una manera de lograr lo que necesitamos?

Aquí hay una versión simplificada de cómo se implementa el componente de traducción en la aplicación frontend: https://codesandbox.io/s/81n874zjp0

Respuesta #1

Sí, hay una manera sencilla

Es posible pasar un arreglo como argumento a una consulta.

Puedes leer más sobre "GraphQL - Listas y No Nulas" aquí

En tu operación de consulta, en lugar de una única key definida como $key: String! puedes pasar un arreglo de claves no nulas así: $keys: [String!]!

También necesitas actualizar tu función resolutora para manejar el arreglo de claves y devolver ya sea un solo Translation o un arreglo de Translation.

Y por último, asegúrate de actualizar tu esquema.

Si estás ejecutando la llamada a la API solo una vez y esperas obtener una sola Translation, debería verse algo así:

type Query {
    translations(language: String!, keys: [String!]!): Translation!
}

type Translation {
    key: String!
    value: String!
}