Apollo-link-rest: [Procura-se ajuda] Uma consulta com uma resposta em que as chaves de objetos dinâmicos são

Criado em 3 jul. 2020  ·  4Comentários  ·  Fonte: apollographql/apollo-link-rest

Estou solicitando dados de esquema do Salesforce. Tem um formato

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

Portanto, os campos são dinâmicos.

Em queries.js, estou tentando descrevê-lo

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

Como posso descrever a parte dinâmica? Não tenho arquivos de esquema ou resolvedores. Apenas queries.js (para outras solicitações com useQuery) e client.js (onde o novo ApolloClient é definido)

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

question❔

Todos 4 comentários

@ssuvorov - Você verificou se a chamada de rede está sendo feita com sucesso?

Se for, então com base apenas em sua resposta de exemplo: Eu faria 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
   }
  }
`;

- Agora, isso pode não funcionar porque o GraphQL espera que cada tipo tenha um nome, então, em vez disso, você pode precisar alterar isso:

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
   }
  }
`;

(Uma maneira alternativa de fazer isso é com um TypePatcher - documentado nos documentos)

Se cada entrada for o mesmo esquema de objeto, você pode até usar um Fragment para ajudá-lo:

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
+ }
 }`;

Se você estiver usando o Salesforce de uma forma genérica e não souber quantas colunas terá, então fica um pouco mais complicado e você precisa usar o patcher de tipo para alterar a forma do API.

Não uso o Salesforce - mas se fosse eu, consideraria perguntar ao meu representante do Salesforce se ele tem uma oferta oficial do GraphQL ou se tem uma oferta de terceiros abençoada para obtê-la nativamente.

Uma rápida pesquisa no Google mostrou que existe: https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000G0l6nUAB - mas só tem uma revisão, então não tenho ideia se é bom.

@fbartho Muito obrigado pela sua resposta. Infelizmente, são mais de 500 campos. Bem, eu tentaria esclarecer com a equipe de SF.

Se precisar processar uma resposta para tornar isso um pouco mais fácil, você pode usar um typenamePatcher, que lhe dará um gancho para remodelar completamente a resposta.

Um esquema melhor / mais genérico pode ter a seguinte aparência:

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

@fbartho Obrigado por sua ajuda. Foi assim que resolvi.

// 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;
    }
  }
});
Esta página foi útil?
0 / 5 - 0 avaliações