Apollo-link-rest: [Hilfe gesucht] Eine Abfrage mit einer Antwort, bei der dynamische Objektschlüssel sind

Erstellt am 3. Juli 2020  ·  4Kommentare  ·  Quelle: apollographql/apollo-link-rest

Ich fordere Daten zum Salesforce-Schema an. Es hat ein Format

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

Felder sind also dynamisch.

In query.js versuche ich es zu beschreiben

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

Wie kann ich den dynamischen Teil beschreiben? Ich habe keine Schemadateien oder Resolver. Nur query.js (für weitere Anfragen mit useQuery) und client.js (wo der neue ApolloClient definiert ist)

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

question❔

Alle 4 Kommentare

@ssuvorov -- Haben Sie überprüft, ob der Netzwerkanruf erfolgreich durchgeführt wurde?

Wenn ja, dann nur basierend auf Ihrer Beispielantwort: Ich würde so etwas tun:

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

-- Dies funktioniert möglicherweise nicht, da GraphQL erwartet, dass jeder Typ einen Namen hat. Stattdessen müssen Sie dies möglicherweise ändern:

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

(Eine alternative Möglichkeit, dies zu tun, ist mit einem TypePatcher - dokumentiert in den Dokumenten)

Wenn jeder Eintrag dasselbe Objektschema ist, können Sie sogar ein Fragment verwenden, um Ihnen zu helfen:

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

Wenn Sie Salesforce generisch verwenden und nicht wissen, wie viele Spalten Sie haben werden, wird es etwas komplizierter und Sie müssen den Typ-Patcher verwenden, um die Form der API.

Ich verwende Salesforce nicht – aber wenn ich es wäre, würde ich meinen Salesforce-Mitarbeiter fragen, ob er ein offizielles GraphQL-Angebot hat oder ob er ein gesegnetes Angebot von Drittanbietern hat, um es nativ zu erhalten.

Eine schnelle Google-Suche zeigte, dass dies existiert: https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000G0l6nUAB – aber es gibt nur eine Rezension, daher habe ich keine Ahnung, ob es gut ist.

@fbartho Vielen Dank für deine Antwort. Leider sind es mehr als 500 Felder. Nun, ich würde versuchen, das mit dem SF-Team zu klären.

Wenn Sie eine Antwort verarbeiten müssen, um dies ein wenig zu vereinfachen, können Sie einen TypnamePatcher verwenden, der Ihnen einen Haken gibt, um die Antwort vollständig umzuformen.

Ein besseres/generischeres Schema könnte praktisch so aussehen:

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

@fbartho Danke für deine Hilfe. So habe ich es gelöst.

// 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;
    }
  }
});
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

blatoo picture blatoo  ·  6Kommentare

karensg picture karensg  ·  5Kommentare

i-Hun picture i-Hun  ·  4Kommentare

Simply007 picture Simply007  ·  5Kommentare

kevinrobayna picture kevinrobayna  ·  6Kommentare