Migraddo koa-grahpql-http-جامعه dev

من به تازگی چالش Woovi را با koa.js و graphql (پیوند پروژه) ایجاد کردم. یکی از مشخصات اختیاری استفاده از آن بود graphql-http، جایگزین برای koa-graphql، که در زمین بازی موجود است. با این حال ، من به برخی از مشکلات اولیه رسیدم: چندین ویژگی در این زمینه وجود نداشت graphql-http، از آنجا که این فقط یک اجرای GraphQL در HTTP است ، یعنی ساده و مینیمالیستی است.
مقدمه – چرا؟ و برخی از مشکلات
اول ، چرا؟ خوب ، مخصوصاً به این دلیل koa-graphql عملاً قطع شد و graphql-http در عوض باید استفاده شود. من این تصمیم را بر اساس بحثی اتخاذ کردم که حتی استفاده از آن را توصیه می کند yoga، با این حال ، یک جایگزین کامل تر برای سرورهای GraphQL ، دیدم که کاملاً قادر به حل آن است graphql-httpبشر اگر می خواهید گزینه قوی تری داشته باشید ، یوگا را امتحان کنید.
بیایید به مشکلات برویم. من از برخی از ویژگی های جالب که قبلاً در آن موجود است استفاده کردم koa-graphql، به عنوان:
- استفاده از a
customErrorFnعلاوه بر این ، برای بازگشت خطاهای سرور به روشی خاصlogarدر کنسول در محیط های آزمایش و توسعه -
graphiql: یک زمین بازی GraphQL برای انجام نمایش داده ها و جهش ها به صورت شهودی توسط مرورگر - تغییر
contextاز این درخواست ، از آنجا که این پروژه در صورت ورود به سیستم کاربر را ذخیره می کند (از طریق Token JWT)
مهاجرت به GraphQL-HTTP
اولین کاری که باید انجام دهید حذف است koa-graphql کاملاً
pnpm un koa-graphql
و اضافه کردن graphql-http:
pnpm i graphql-http
این برای شروع تطبیق ویژگی ها است.
ایجاد کنترل کننده
به دنبال قطعه ای که در readme وجود دارد graphql-http، برای ایجاد کنترل کننده بسیار ساده است ، فقط وارد کنید createHandler برای koa و ایجاد طرح و زمینه:
import { createHandler } from 'graphql-http/lib/use/koa';
const graphqlHandler = createHandler({
schema,
context: async (ctx) => {
const { user } = await getUser(ctx);
return getContext({ ctx, user });
},
});
خوب ، این طرح ساده ترین قسمت است ، فقط از طرحواره قبلی تنظیم شده است. با این حال ، من با انواع مختلفی مشکل داشتم context، به خصوص از آنجا که اطلاعات هدر می تواند متفاوت باشد.
تطبیق انواع زمینه
هیچ get-context.ts، من نوعی را که باید برای متن دریافت کنم ایجاد کردم:
import type { Request } from 'graphql-http';
import type { IncomingMessage } from 'node:http';
import type { RequestContext } from 'graphql-http/lib/use/koa';
export type RequestGraphQLContext = Request<IncomingMessage, RequestContext>;
حالا برای get-user.ts، قبل از اینکه من به سادگی ارزش آن را بگیرم context.headers.authorization، اما اکنون تایپ برای headers کاملاً متفاوت است:
- استفاده از آن ضروری است
context.headers.get -
getاین می تواند یک تابع ، یک رشته باشد ، یا حاوی آرایه در مقدار آن باشد
بنابراین ، من یک تابع ایجاد کردم تا به درستی اعتبارسنجی کند ، get-graphql-http-headers.ts:
import { Request } from 'graphql-http';
import { RequestContext } from 'graphql-http/lib/use/koa';
import { IncomingMessage } from 'node:http';
type HeaderKeyType = 'authorization';
export function getGraphQLHttpHeaders(
ctx: Request<IncomingMessage, RequestContext>,
headerKey: HeaderKeyType
) {
if (typeof ctx.headers.get === 'function') {
return ctx.headers.get(headerKey);
}
if (typeof ctx.headers === 'object') {
const header = (
ctx.headers as Record<string, string | string[] | undefined>
)[headerKey];
if (Array.isArray(header)) {
return header[0] ?? null;
} else if (typeof header === 'string') {
return header;
}
}
return null;
}
حالا ، برای گرفتن authToken، فقط از عملکرد ایجاد شده استفاده کنید:
const authHeader = getGraphQLHttpHeaders(ctx, 'authorization');
طرحواره و زمینه آماده! اکنون ویژگی ها از دست رفته اند: graphiql و درمان خطا
درمان خطا
حالا حتی ساده تر است! ما لازم نیست که یک عملکرد را به کنترل کننده جدید منتقل کنیم ، فقط یک میان افزار اضافه کنید!
// graphql error handling middleware
app.use(async (ctx, next) => {
try {
await next();
} catch (error) {
if (error instanceof GraphQLError) {
if (logEnvironments.includes(config.NODE_ENV)) {
console.log(error.message);
console.log(error.locations);
console.log(error.stack);
}
ctx.body = {
errors: [
{
message: error.message,
locations: error.locations,
stack: config.NODE_ENV === 'development' ? error.stack : undefined,
},
],
};
} else {
throw error;
}
}
});
Graphiql – زمین بازی
در اینجا من نحوه دسترسی به زمین بازی را تغییر دادم. همانطور که فقط در یک محیط توسعه استفاده می شود ، من تصمیم گرفتم از ruru و یک اسکریپت را به pack.json از سرور اضافه کنید تا به آن دسترسی پیدا کنید. برای این ، او از بسته سؤال می کند ruru نصب شود ، این حتی می تواند در هر نقطه پایانی GraphQL در دسترس باشد!
npx ruru -SP -p 3001 -e http://localhost:3000/graphql
-
-pدرب زمین بازی را مشخص می کند -
-eمسیر سرور GraphQL را مشخص می کند
پایان
او تمام شد! با آن ، من مقداری KBS را ذخیره کردم:
و به طور عمده ، من به یک Lib بیشتر به روز -دات به روز کردم.
در پروژه GitHub من دقیقاً می بینید که چگونه خط فکری من تجسم مسئله و درخواست کشیدن است. و دیگری: یک جایزه وجود دارد که من پیکربندی کردم graphiql در یک برنامه react-router v7 (ریمیکس قدیمی) ، ارزش دیدن دارد!
اگر سوالی دارید ، در هر یک از پیوندهای من با من تماس بگیرید یا با من تماس بگیرید
منابع
Foto de Mohammad Rahmani na Unsplash



