برنامه نویسی

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 را ذخیره کردم:

مقایسه اندازه بین بسته های GraphQL-HTTP و KoA-Graphql. GraphQL-HTTP دارای 2.2 کیلوبایت اندازه گیری شده و 1.0 کیلوبایت در هنگام فشرده سازی با GZIP است. Koa-Graphql دارای 2987.3 KB Minified و 840.9 KB با GZIP است. اطلاعات از Fonte Bundlephobia است ، با پیوندهایی به Github و Bundlephobia در زیر هر بسته موجود است

و به طور عمده ، من به یک Lib بیشتر به روز -دات به روز کردم.

در پروژه GitHub من دقیقاً می بینید که چگونه خط فکری من تجسم مسئله و درخواست کشیدن است. و دیگری: یک جایزه وجود دارد که من پیکربندی کردم graphiql در یک برنامه react-router v7 (ریمیکس قدیمی) ، ارزش دیدن دارد!

اگر سوالی دارید ، در هر یک از پیوندهای من با من تماس بگیرید یا با من تماس بگیرید

منابع

Foto de Mohammad Rahmani na Unsplash

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا