Halo semua,
Saya ingin menggunakan apollo-link-rest untuk mengakses api istirahat, namun, saya tidak dapat per useQuery() mengakses response.headers
.
Misalnya, rest api dengan pagination, yang menempatkan informasi first, prev, next, last
di header. Bagaimana saya bisa mengakses itu?
Saya membuat contoh di sini: https://codesandbox.io/embed/how-to-access-response-0mqx7?file=/src/Client.ts
Anda dapat pergi ke tab develop tools Network
, lihat responsnya dengan Header , di tautan , ada informasi pagination. Tapi saya tidak tahu, bagaimana cara mengakses Headers
....
Hier adalah kode utama saya, saya tidak tahu, bagaimana cara mendapatkan response.headers.link
...
const queryTodos = gql`
query Todos($page: number, $limit: number) {
todos(_page: $page, _limit: $limit)
@rest(type: "[Todo]", path: "/todos/?{args}") {
userId
id
title
completed
}
}
`;
export const Todos = () => {
const { data, loading, error } = useQuery(queryTodos, {
variables: { page: 1, limit: 3 },
fetchPolicy: "no-cache"
});
...
return (<div>...</div>)
Saya juga menanyakan pertanyaan ini di stackoverflow: https://stackoverflow.com/q/64791676/3279996 , jika Anda menghargai memiliki lebih banyak poin di stackoverflow. :D
@blatoo -- sayangnya, itu adalah fitur yang saat ini tidak ada di apollo-link-rest.
Pada dasarnya, GraphQL tidak berharap untuk berurusan dengan Header -- karena itu harus dikembalikan jauh di dalam grafik.
Jika seseorang ingin menerapkan ini, saya dapat melihat kami menambahkan __headers
sebagai bidang rahasia/otomatis di "tubuh" respons, tetapi kami harus menambahkan flag fitur untuk mengaktifkan perilaku ini, dan lakukan beberapa mangling ke tombol header agar kompatibel dengan graphql.
const queryTodos = gql`
query Todos($page: number, $limit: number) {
todos(_page: $page, _limit: $limit)
@rest(type: "[Todo]", path: "/todos/?{args}") {
+ __headers {
+ XMyHeader
+ }
userId
id
title
completed
}
}
`;
@fbartho terima kasih banyak atas jawaban ini. Ini akan menjadi fitur yang hebat, jika kita dapat mengakses informasi header. Saya menggunakan json-server, mereka meletakkan informasi pagination di Headers
, juga untuk info pagination berbasis kursor.
Omong-omong, saya melihat di dokumentasi Anda ada: opsi responseTansformer
dan customFetch
. Dapatkah saya melakukan sesuatu dengan mereka untuk mendapatkan informasi pagination??? Sebenarnya saya sudah mencoba banyak, tetapi masih belum berhasil ...:
https://www.apollographql.com/docs/link/links/rest/#response -transforming
https://www.apollographql.com/docs/link/links/rest/#custom -fetch
Sayangnya, apollo-link-rest
bergantung pada apollo-link
's API untuk dihubungkan ke GraphQL -- tetapi ini berarti saya tidak berpikir ada cara yang jelas untuk membagikan JS Headers
API secara langsung -- tetapi versi denormalisasi itu mungkin.
Yang mengatakan, opsi responseTransformer
atau customFetch
dapat digunakan untuk menambal apa yang Anda butuhkan.
responseTransformer
menerima objek JS Response
yang memiliki atribut response.headers
.
Jadi Anda bisa menulis sesuatu seperti ini:
responseTransformer: async (resp: Response) => {
const body = await resp.json();
const interestingHeaders = {};
interestingHeaders.headerOne = resp.headers.get("headerOne"); // Pluck out the headers you want
body.__headers = interestingHeaders
return body;
}
Tergantung pada versi browser Anda, Anda mungkin dapat menggunakan headers.entries()
untuk mendapatkan semua header sebagai satu objek alih-alih headers.get()
-- tetapi saat ini tidak tersedia di Safari-iOS.
Ini jelas disederhanakan, dan penanganan kesalahan diserahkan kepada Anda, tetapi saya pikir ini akan berhasil!
customFetch
juga bisa, tapi menurut saya responseTransformer
lebih mudah.
@fbartho Wow, ini keren! Saya baru saja mencoba kode Anda, itu berfungsi dan saya mendapatkan tautannya.
Sekarang muncul masalah lain, bagaimana saya bisa mengakses body.__headers.link
dalam kueri?
kode kueri saya adalah:
const queryTodos = gql`
query Todos($page: number, $limit: number) {
todos(_page: $page, _limit: $limit)
@rest(type: "TodoPagination", path: "/todos/?{args}") {
__headers {
link
}
userId
id
title
completed
}
}
`;
Tapi apa nilai __headers
adalah nol...
Kodenya ada di sini: Saya menambahkan kode Anda di Client.ts
dan kode Kueri ada di Todo.tsx
:
https://codesandbox.io/s/how-to-access-response-0mqx7?file=/src/Todos.tsx
@fbartho Hai, saya mencoba tiga cara berbeda, akhirnya, saya menyelesaikan masalah ini akhirnya. Namun, saya masih ragu, apakah itu solusi yang baik. Bisakah Anda memberi saya pendapat Anda?
Metode 1: gagal.
Pada awalnya, saya pikir, saya dapat menanyakan __headers
di useQuery()
, mencoba beberapa kali, tetapi gagal.
Metode 2: tidak mencoba, karena saya meragukan solusinya
ubah struktur respons di responseTransformer
, masukkan __headers
di kunci __headers
dan juga masukkan daftar tugas di kunci todo
. Namun, saya pikir, itu bukan solusi yang baik. Sebab, semua struktur respon akan berubah. Jadi saya harus menulis ulang semua struktur di useQuery()
.
Metode 3: sukses dan sangat sederhana
Saya menempatkan __headers
dalam variabel reaktif. Dalam fungsi responseTransformer
, saya hanya memasukkan nilai __headers
dalam variabel reaktif, dan menanyakannya setelah useQuery()
dieksekusi. Namun, saya masih tidak yakin, karena, saya harus membuat variabel reaktif yang berbeda untuk kueri yang berbeda...
@blatoo , ini adalah masalah yang lebih lama, yang baru saja saya temui, menyelesaikannya dengan new ApolloLink
const paginationLink = new ApolloLink((operation, forward) => {
return forward(operation).map((response) => {
const context = operation.getContext();
const { headers } = context.restResponses[0] || null;
// in my case i'm making a bunch of sub queries, so i'm using `[0]` to get the headers from the top level.
if (headers) {
const pagination = getPaginationFromHeaders(headers.get('link'));
return { ...response, data: { ...response.data, pagination } };
}
return response;
});
});
const client = new ApolloClient({
cache: new InMemoryCache(),
link: concat(paginationLink, restLink),
});