Apollo-link-rest: [Se busca ayuda] Una consulta con una respuesta donde las claves de objetos dinámicos son

Creado en 3 jul. 2020  ·  4Comentarios  ·  Fuente: apollographql/apollo-link-rest

Solicito datos de esquema de Salesforce. Tiene un formato

res = {
  Id: { name, type, label },
  IsDeleted: { type, name, label },
  MasterRecordId: { type, name, label },
 ...and so on
}

Entonces, los campos son dinámicos.

En queries.js estoy tratando de describirlo

export const GET_SALESFORCE_FIELDS = gql`
  query SalesforceFields {
    salesforceFields @rest(endpoint: "schemaservice", type: "SalesforceFields", path: "/fields") {
       // What should be here??
   }
  }
`;
`

¿Cómo puedo describir la parte dinámica? No tengo ningún archivo de esquema ni solucionador. Solo queries.js (para más solicitudes con useQuery) y client.js (donde se define el nuevo ApolloClient)

"@ apollo / client": "^ 3.0.0-rc.10",
"apollo-link-rest": "^ 0.8.0-beta.0",

question❔

Todos 4 comentarios

@ssuvorov : ¿ha verificado que la llamada de red se realiza correctamente?

Si es así, basándome solo en su respuesta de ejemplo: haría algo como:

export const GET_SALESFORCE_FIELDS = gql`
  query SalesforceFields {
    salesforceFields @rest(endpoint: "schemaservice", type: "SalesforceFields", path: "/fields") {
       Id {
         type, name, label
       }
       IsDeleted {
         type, name, label
       }
       # …remaining fields
   }
  }
`;

- Ahora, esto podría no funcionar porque GraphQL espera que cada tipo tenga un nombre, por lo que es posible que deba cambiar esto:

export const GET_SALESFORCE_FIELDS = gql`
  query SalesforceFields {
    salesforceFields @rest(endpoint: "schemaservice", type: "SalesforceFields", path: "/fields") {
-      Id {
+      Id @type(name: "FieldDescriptor") {
         type, name, label
       }
-      IsDeleted {
+      IsDeleted @type(name: "FieldDescriptor") {
         type, name, label
       }
       # …remaining fields
   }
  }
`;

(Una forma alternativa de hacer esto es con un TypePatcher, documentado en los documentos)

Si cada entrada es el mismo esquema de objeto, incluso puede usar un Fragmento para ayudarlo a:

export const GET_SALESFORCE_FIELDS = gql`
  query SalesforceFields {
    salesforceFields @rest(endpoint: "schemaservice", type: "SalesforceFields", path: "/fields") {
       Id @type(name: "FieldDescriptor") {
-          type, name, label
+          ...FieldFrag
       }
       IsDeleted @type(name: "FieldDescriptor") {
-          type, name, label
+          ...FieldFrag
       }
       # …remaining fields
   }
+ fragment FieldFrag on FieldDescriptor {
+    type
+    name
+    label
+ }
 }`;

Si está utilizando Salesforce de forma genérica y no sabe cuántas columnas va a tener, entonces se vuelve un poco más complicado y necesita usar el parche de tipo para cambiar la forma del API.

No uso Salesforce, pero si fuera yo, consideraría preguntarle a mi representante de Salesforce si tienen una oferta oficial de GraphQL o si tienen una oferta de terceros bendecida para obtenerla de forma nativa.

Una búsqueda rápida en Google mostró que esto existe: https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000G0l6nUAB - pero solo tiene una revisión, así que no tengo idea si es bueno.

@fbartho Muchas gracias por tu respuesta. Desafortunadamente, son más de 500 campos. Bueno, trataría de aclararlo con el equipo de SF.

Si necesita procesar una respuesta para hacerlo un poco más fácil, puede usar un typenamePatcher, que le dará un gancho para remodelar completamente la respuesta.

Un esquema mejor / más genérico podría verse virtualmente así:

type MyResponse (
  columns: [Column!]!
}
type Column {
  name: String!
  type: String!
  label: String!
}

@fbartho Gracias por tu ayuda. Así es como lo resolví.

// queries.js
export const GET_SALESFORCE_FIELDS = gql`
  query SalesforceFields {
    salesforceFields @rest(endpoint: "schemaservice", type: "SalesforceFieldsPayload", path: "/fields") {
      items @type(name: "Salesforce")
    }
  }
`;

// client.js
const restLink = new RestLink({
  ...,
  typePatcher: {
    SalesforceFieldsPayload: (
      data,
      outerType,
      patchDeeper
    ) => {
      if (data != null) {
        data.items = Object.keys(data).map(field => ({ __typename: "Salesforce", ...data[field] }));
      }
      return data;
    }
  }
});
¿Fue útil esta página
0 / 5 - 0 calificaciones