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