Я запрашиваю данные схемы Salesforce. Имеет формат
res = {
Id: { name, type, label },
IsDeleted: { type, name, label },
MasterRecordId: { type, name, label },
...and so on
}
Итак, поля динамические.
В query.js я пытаюсь описать это
export const GET_SALESFORCE_FIELDS = gql`
query SalesforceFields {
salesforceFields @rest(endpoint: "schemaservice", type: "SalesforceFields", path: "/fields") {
// What should be here??
}
}
`;
`
Как я могу описать динамическую часть? У меня нет файлов схемы или преобразователей. Только query.js (для дальнейших запросов с useQuery) и client.js (где определен новый ApolloClient)
"@ apollo / client": "^ 3.0.0-rc.10",
"apollo-link-rest": "^ 0.8.0-beta.0",
@ssuvorov - Вы проверили, что сетевой вызов выполняется успешно?
Если это так, то, основываясь только на вашем примере ответа: я бы сделал что-то вроде:
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
}
}
`;
- Теперь это может не сработать, потому что GraphQL ожидает, что у каждого типа будет имя, поэтому вместо этого вам может потребоваться изменить это:
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
}
}
`;
(Альтернативный способ сделать это - с помощью TypePatcher - задокументировано в документации)
Если каждая запись представляет собой одну и ту же схему объекта, вы даже можете использовать фрагмент, чтобы помочь вам:
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
+ }
}`;
Если вы используете Salesforce обычным образом и не знаете, сколько столбцов у вас будет, тогда все становится немного сложнее, и вам нужно использовать патчер типов, чтобы изменить форму API.
Я не использую Salesforce, но если бы это был я, я бы подумал о том, чтобы спросить моего представителя Salesforce, есть ли у них официальное предложение GraphQL или есть ли у них благословенное стороннее предложение, чтобы получить его изначально.
Быстрый поиск в Google показал, что это существует: https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000G0l6nUAB - но у него только один обзор, поэтому я понятия не имею, насколько он хорош.
@fbartho Большое спасибо за ваш ответ. К сожалению, это более 500 полей. Что ж, я попробую уточнить у команды SF.
Если вам нужно обработать ответ, чтобы сделать это немного проще, вы можете использовать typenamePatcher, который даст вам возможность полностью изменить форму ответа.
Лучшая / более общая схема может выглядеть примерно так:
type MyResponse (
columns: [Column!]!
}
type Column {
name: String!
type: String!
label: String!
}
@fbartho Спасибо за вашу помощь. Вот как я это решил.
// 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;
}
}
});