Apollo-link-rest: [Dicari bantuan] Kueri dengan respons di mana kunci objek dinamis berada

Dibuat pada 3 Jul 2020  ·  4Komentar  ·  Sumber: apollographql/apollo-link-rest

Saya meminta data skema Salesforce. Ini memiliki format

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

Jadi, bidang itu dinamis.

Di query.js saya mencoba menggambarkannya

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

Bagaimana saya bisa menggambarkan bagian dinamis? Saya tidak memiliki file skema atau resolver. Hanya query.js (untuk permintaan lebih lanjut dengan useQuery) dan client.js (di mana ApolloClient baru didefinisikan)

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

question❔

Semua 4 komentar

@ssuvorov -- Sudahkah Anda memverifikasi bahwa panggilan jaringan berhasil dilakukan?

Jika ya, maka hanya berdasarkan respons contoh Anda: Saya akan melakukan sesuatu seperti:

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

-- Sekarang, ini mungkin tidak berfungsi karena GraphQL mengharapkan setiap jenis memiliki nama, jadi Anda mungkin perlu mengubah ini:

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

(Cara alternatif untuk melakukan ini adalah dengan TypePatcher -- didokumentasikan dalam dokumen)

Jika setiap entri adalah skema objek yang sama, Anda bahkan dapat menggunakan Fragmen untuk membantu Anda:

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

Jika Anda menggunakan Salesforce secara umum, dan Anda tidak tahu berapa banyak kolom yang akan Anda miliki, maka itu akan menjadi sedikit lebih rumit, dan Anda perlu menggunakan type-patcher untuk mengubah bentuk API.

Saya tidak menggunakan Salesforce -- tetapi jika itu saya, saya akan mempertimbangkan untuk bertanya kepada Perwakilan Salesforce saya apakah mereka memiliki Penawaran GraphQL resmi, atau jika mereka memiliki penawaran pihak ke-3 yang diberkati untuk mendapatkannya secara asli.

Pencarian google cepat menunjukkan ini ada: https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000G0l6nUAB - tetapi hanya memiliki satu ulasan, jadi saya tidak tahu apakah itu bagus.

@fbartho Terima kasih banyak atas balasan Anda. Sayangnya, itu lebih dari 500 bidang. Nah, saya coba klarifikasi dengan tim SF.

Jika Anda perlu memproses respons untuk membuatnya sedikit lebih mudah, Anda dapat menggunakan typenamePatcher, yang akan memberi Anda pengait untuk membentuk kembali respons sepenuhnya.

Skema yang lebih baik/lebih umum mungkin terlihat seperti ini:

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

@fbartho Terima kasih atas bantuan Anda. Ini adalah bagaimana saya menyelesaikannya.

// 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;
    }
  }
});
Apakah halaman ini membantu?
0 / 5 - 0 peringkat