أهلا بكم،
يجب أن أستخدم apollo-link-rest للوصول إلى بقية api ، ومع ذلك ، لا يمكنني الوصول لكل useQuery () إلى response.headers
.
على سبيل المثال ، واجهة برمجة تطبيقات راحة مع ترقيم صفحات ، والتي تضع معلومات first, prev, next, last
في رأس الصفحة. كيف يمكنني الوصول إلى ذلك؟
لقد قدمت مثالًا هنا: https://codesandbox.io/embed/how-to-access-response-0mqx7؟file=/src/Client.ts
يمكنك الانتقال إلى علامة التبويب أدوات التطوير Network
، شاهد الرد باستخدام الرؤوس ، في الرابط ، توجد معلومات ترقيم الصفحات. لكن ليس لدي أي فكرة عن كيفية الوصول إلى Headers
....
ها هو الكود الرئيسي ، ليس لدي فكرة ، كيف أحصل على 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>)
لقد طرحت أيضًا هذا السؤال في stackoverflow: https://stackoverflow.com/q/64791676/3279996 ، في حال كنت ممتنًا للحصول على المزيد من النقاط في stackoverflow. :د
blatoo - للأسف ، هذه ميزة غير موجودة حاليًا في Apollo-link-rest.
بشكل أساسي ، لا تتوقع GraphQL التعامل مع الرؤوس - لأنه يجب أن تكون هذه الرؤوس قابلة للإرجاع في عمق الرسم البياني.
إذا أراد شخص ما تنفيذ ذلك ، فيمكنني رؤيتنا بإضافة __headers
كحقل سري / تلقائي في "نص" الاستجابة ، ولكن يتعين علينا إضافة علامة ميزة لتمكين هذا السلوك ، و قم ببعض التغيير في مفاتيح الرأس بحيث تكون متوافقة مع 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 شكرا جزيلا على هذه الإجابة. ستكون ميزة رائعة ، إذا تمكنا من الوصول إلى معلومات الرأس. أستخدم خادم json ، وضعوا معلومات ترقيم الصفحات في Headers
، أيضًا لمعلومات ترقيم الصفحات المستندة إلى المؤشر.
بالمناسبة ، رأيت في وثائقك: خيارات responseTansformer
و customFetch
. هل يمكنني فعل شيء معهم للحصول على معلومات ترقيم الصفحات ؟؟؟ في الواقع لقد حاولت كثيرًا ولكن لم تنجح بعد ...:
https://www.apollographql.com/docs/link/links/rest/#response -transforming
https://www.apollographql.com/docs/link/links/rest/#custom -fetch
للأسف، apollo-link-rest
تعتمد على apollo-link
الصورة API إلى سد العجز في GraphQL - ولكن يعني ذلك أنني لا أعتقد أن هناك طريقة واضحة للمشاركة في JS Headers
API مباشرة - ولكن قد يكون من الممكن إصدار نسخة غير طبيعية منه.
ومع ذلك ، يمكن استخدام خيارات responseTransformer
أو customFetch
لتصحيح ما تحتاجه.
و responseTransformer
يتلقى JS Response
الكائن الذي لديه response.headers
السمة.
لذلك يمكنك كتابة شيء مثل هذا:
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;
}
اعتمادًا على إصدار المستعرض الخاص بك ، قد تتمكن من استخدام headers.entries()
للحصول على جميع الرؤوس ككائن واحد بدلاً من headers.get()
- لكن هذا غير متوفر حاليًا في Safari-iOS.
من الواضح أن هذا مبسط ، ويتم ترك معالجة الأخطاء لك ، لكنني أعتقد أن هذا سينجح!
customFetch
يمكنه أيضًا القيام بذلك ، لكنني أعتقد أن responseTransformer
أسهل.
fbartho نجاح باهر ، هذا رائع! لقد جربت الكود الخاص بك للتو ، لقد نجح الأمر وحصلت على الرابط.
الآن تأتي مشكلة أخرى ، كيف يمكنني الوصول إلى الاستعلام body.__headers.link
؟
كود الاستعلام الخاص بي هو:
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
}
}
`;
ولكن ما قيمة __headers
خالية ...
الكود هنا: لقد أضفت الكود الخاص بك في Client.ts
وكود الاستعلام موجود بـ Todo.tsx
:
https://codesandbox.io/s/how-to-access-response-0mqx7؟file=/src/Todos.tsx
fbartho مرحبًا ، لقد جربت ثلاث طرق مختلفة ، أخيرًا ، لقد حللت هذه المشكلة أخيرًا. ومع ذلك ، ما زلت أشك في ما إذا كان هذا حلًا جيدًا. هل تستطيع أن تعطيني رأيك؟
الأسلوب 1: فشل.
في البداية ، أعتقد أنه يمكنني الاستعلام عن __headers
في useQuery()
، حاولت عدة مرات ، لكنها فشلت.
الطريقة الثانية: لم أحاول ، لأنني أشك في الحل
قم بتغيير بنية الاستجابة في responseTransformer
، ضع __headers
في مفتاح __headers
وقم أيضًا بوضع قائمة المهام في مفتاح todo
. ومع ذلك ، أعتقد أنه ليس حلاً جيدًا. لأنه سيتم تغيير كل بنية الاستجابة. لذلك لا بد لي من إعادة كتابة كل الهيكل في useQuery()
.
الطريقة الثالثة: النجاح والميت البسيط
أضع __headers
في متغير تفاعلي. في الدالة responseTransformer
، وضعت قيمة __headers
في متغير تفاعلي ، واستعلم عنها بعد تنفيذ useQuery()
. ومع ذلك ، ما زلت غير متأكد ، لأنه لا بد لي من عمل متغير تفاعلي مختلف لاستعلام مختلف ...
blatoo ، هذه مشكلة قديمة ، وحلتها بـ 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),
});