بناء ونشر خادم GraphQL على AWS Lambda باستخدام Node.js و CloudFormation

دقائق القراءة: 13

مقدمة في عالم GraphQL و AWS Lambda

في عالم تطوير الواجهات البرمجية (APIs) سريع التطور، أصبحت المرونة والكفاءة مطلبين أساسيين. لقد أمضيت سنوات في بناء واجهات GraphQL البرمجية في بيئات لا خادمية (Serverless)، وأجد صعوبة في تخيل العودة إلى العمل مع واجهات RESTful APIs التقليدية. عندما تجمع قوة GraphQL مع قابلية التوسع اللامحدودة لخدمة AWS Lambda، تحصل على خادم قادر على التعامل مع كميات هائلة من حركة المرور بكفاءة لا مثيل لها.

في هذا الدليل الشامل، سنتعلم خطوة بخطوة كيفية بناء ونشر خادم GraphQL على AWS Lambda، والوصول إليه عبر نقطة نهاية (endpoint) من API Gateway. سنستخدم CloudFormation و AWS CLI لنشر جميع موارد AWS الخاصة بنا ورمز التطبيق البرمجي، مما يضمن عملية نشر آلية وقابلة للتكرار.

ماذا سنتناول في هذا الدليل؟

  • بناء خادم GraphQL باستخدام Apollo Server.
  • نشر خادم GraphQL هذا على AWS Lambda.
  • استخدام API Gateway لترحيل الطلبات إلى Lambda.
  • استخدام CloudFormation لنشر حزمة التطبيق (application stack) على AWS.
  • إعداد Lambda للعملية التطويرية المحلية.

ملاحظة سريعة: يمكنك الحصول على الكود المصدري الكامل للتطبيق من Github.

ما هو GraphQL؟

GraphQL هي لغة استعلام (query language) لوصف الواجهات البرمجية (APIs) باستخدام نظام مخطط (schema system) قوي ومحدد الأنواع. يقوم خادم GraphQL بتلبية هذه الاستعلامات باستخدام البيانات الموجودة. فيما يلي بعض المزايا الرئيسية لاستخدام GraphQL:

استعلام البيانات التي يحتاجها تطبيقك فقط

على عكس واجهات REST APIs، يُمكّن GraphQL العملاء من استعلام البيانات التي يحتاجونها بدقة فقط. يقوم الخادم بتلبية طلب العميل عن طريق إرجاع ما يطلبه العميل فقط، مما يقلل من حجم البيانات المنقولة ويزيد من كفاءة الاتصال.

نظام قوي ومحدد الأنواع

يُمكّن نظام GraphQL القوي والمحدد الأنواع المستخدمين من فحص المخطط (schema) بأكمله. تعمل واجهة GraphQL API كتوثيق واضح لقدرات الخادم وتُعلمك بالأخطاء أثناء عملية التطوير، مما يقلل من الأخطاء ويسرع عملية التطوير.

تجميع استعلاماتك في طلب واحد

مع GraphQL، يمكنك استعلام موارد متعددة والحصول على استجابات مجمعة بطلب واحد. بفضل عدد أقل من الطلبات، تعمل التطبيقات التي تستخدم GraphQL بشكل أسرع بكثير، مما يحسن تجربة المستخدم.

ما هي AWS Lambda؟

AWS Lambda هي خدمة حوسبة تقدمها AWS تتيح لك تشغيل رمز التطبيق الخاص بك دون الحاجة إلى إدارة أي خوادم. تتولى AWS جميع الأعباء العامة مثل البنية التحتية، والأمان، والموارد، ونظام التشغيل، والتصحيحات، حتى يتمكن المطورون من التركيز فقط على بناء التطبيق، مما يوفر وقتًا وجهدًا كبيرين.

لنبدأ العمل: إعداد المشروع

لنبدأ بإنشاء مجلد للمشروع. ثم، انتقل إلى المجلد وقم بتهيئة مشروع Node.js. في الأمثلة التالية، أستخدم Node 10.x. يمكنك تثبيت إصدار Node الذي تختاره باستخدام asdf.

mkdir apollo-server-lambda-nodejs
cd apollo-server-lambda-nodejs
yarn init

بعد ذلك، أنشئ مجلدًا يضم جميع الكود المصدري الخاص بنا.

mkdir src

أخيرًا، أنشئ ملف index داخل مجلد src الذي سيعمل كمعالج لـ Lambda (lambda handler).

cd src
touch index.js

تهيئة مشروع Node.js وإنشاء الملفات الأساسية

املأ ملف index.js بالكود التالي:

exports.handler = async () => {
  return {
    body: 'Hello from Lambda'
  };
};

الكود أعلاه هو معالج Lambda بسيط للغاية سيعيد Hello from Lambda عند استدعائه. لنقم أولاً بنشر الكود الخاص بنا إلى AWS Lambda.

تجهيز كود التطبيق للنشر

قبل أن نتمكن من نشر الكود الخاص بنا إلى Lambda، نحتاج إلى إنشاء ملف مضغوط (zip) لتطبيقنا وتحميله إلى سلة تخزين S3. سنستخدم AWS CLI لإنشاء السلة. إذا لم تكن قد قمت بإعداد AWS CLI بعد، فاتبع هذا الدليل لإعداده الآن.

أنشئ سلة S3 لاستخدامها في نشر الكود الخاص بنا إلى Lambda. اختر اسمًا فريدًا لسلة S3 الخاصة بك. أسماء السلات فريدة عالميًا عبر جميع مناطق AWS.

aws s3 mb s3://lambda-deploy-asln

أنشئ أرشيفًا للتطبيق باستخدام أمر zip وتحقق من الملفات داخل الملف المضغوط.

zip -rq dist-latest.zip src package.json
zipinfo dist-latest.zip

انسخ ملف zip إلى S3 باستخدام أمر AWS CLI.

aws s3 cp dist-latest.zip s3://lambda-deploy-asln/dist-latest.zip

أخيرًا، استخدم الأمر التالي للتحقق من وجود الملف في S3.

aws s3 ls s3://lambda-deploy-asln

نسخ حزمة التطبيق إلى سلة S3

الآن بعد أن قمنا بنشر التطبيق المعبأ إلى S3، نحتاج بعد ذلك إلى إعداد Lambda و API Gateway في AWS. في القسم التالي، سنستخدم CloudFormation لإعداد جميع موارد AWS الضرورية.

إعداد AWS Lambda مع تكامل API Gateway Proxy

CloudFormation هي خدمة AWS تساعدنا في كتابة البنية التحتية ككود (Infrastructure as Code). تجعل CloudFormation عملية إنشاء وإدارة موارد التطبيق بسيطة للغاية. دعنا نستخدم CloudFormation لتحديد حزمتنا (stack).

أنشئ ملفًا باسم cloudformation.yml في جذر المشروع.

touch cloudformation.yml

أضف الكود التالي إلى ملف cloudformation.yml:

---
Description: GraphQL server on AWS lambda
Parameters:
  Version:
    Description: Application version number
    Type: String
  BucketName:
    Description: S3 bucket name where the source code lives
    Type: String
Resources:
  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: !Ref BucketName
        S3Key: !Sub dist-${Version}.zip
      Handler: src/index.handler
      Description: GraphQL Apollo Server
      Role: !GetAtt LambdaExecutionRole.Arn
      Runtime: nodejs10.x
      Timeout: 10
  LambdaExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Policies:
        - PolicyName: "LambdaFunctionPolicy"
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"
  GraphQLApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: apollo-graphql-api
  GraphQLApiResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      ParentId: !GetAtt GraphQLApi.RootResourceId
      RestApiId: !Ref GraphQLApi
      PathPart: 'graphql'
  GraphQLApiMethod:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref GraphQLApi
      ResourceId: !Ref GraphQLApiResource
      AuthorizationType: None
      HttpMethod: POST
      Integration:
        Type: AWS_PROXY
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations
  GraphQLApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    Properties:
      RestApiId: !Ref GraphQLApi
      StageName: v1
    DependsOn:
      - GraphQLApiResource
      - GraphQLApiMethod
  GraphQLApiPermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      Action: lambda:invokeFunction
      FunctionName: !GetAtt LambdaFunction.Arn
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${GraphQLApi}/*
Outputs:
  ApiUrl:
    Description: Invoke url of API Gateway endpoint
    Value: !Sub https://${GraphQLApi}.execute-api.${AWS::Region}.amazonaws.com/v1/graphql

أعلم أن هناك الكثير يحدث في هذا القالب. دعنا نفحص الكود خطوة بخطوة.

معلمات القالب (Template Parameters)

أولاً، نحدد بعض المعلمات التي نستخدمها في القالب. يمكننا تمرير هذه المتغيرات كتجاوزات للمعلمات (parameter overrides) عند نشر حزمة CloudFormation.

Description: GraphQL server on AWS lambda
Parameters:
  Version:
    Description: Application version number
    Type: String
  BucketName:
    Description: S3 bucket name where the source code lives
    Type: String

دالة Lambda

نحدد دالة Lambda الخاصة بنا مع تحديد المسار الذي يجب أن تسحب منه كود التطبيق. هذه السلة هي نفسها التي أنشأناها سابقًا.

LambdaFunction:
  Type: AWS::Lambda::Function
  Properties:
    Code:
      S3Bucket: !Ref BucketName
      S3Key: !Sub dist-${Version}.zip
    Handler: src/index.handler
    Description: GraphQL Apollo Server
    Role: !GetAtt LambdaExecutionRole.Arn
    Runtime: nodejs10.x
    Timeout: 10

نريد أن تكون دالة Lambda الخاصة بنا قادرة على إرسال سجلات التطبيق إلى AWS CloudWatch. تتطلب Lambda أذونات خاصة لتتمكن من كتابة السجلات إلى CloudWatch. لذلك، نقوم بإنشاء دور (role) يُمكّن الكتابة إلى CloudWatch ونقوم بتعيينه لدالة Lambda.

LambdaExecutionRole:
  Type: "AWS::IAM::Role"
  Properties:
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: "Allow"
          Principal:
            Service:
              - "lambda.amazonaws.com"
          Action:
            - "sts:AssumeRole"
    Policies:
      - PolicyName: "LambdaFunctionPolicy"
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - logs:CreateLogGroup
                - logs:CreateLogStream
                - logs:PutLogEvents
              Resource: "*"

API Gateway

نريد أيضًا نقطة نهاية HTTP لاستدعاء دالة Lambda. يمكن استخدام API Gateway لإنشاء نقطة نهاية HTTP. يمكننا بعد ذلك تكوين API Gateway لترحيل جميع الطلبات الواردة من العميل إلى دالة Lambda وإرسال الاستجابة من Lambda مرة أخرى إلى العميل.

أولاً، نقوم بإنشاء API Gateway RestApi.

GraphQLApi:
  Type: 'AWS::ApiGateway::RestApi'
  Properties:
    Name: apollo-graphql-api

ثم، نقوم بإنشاء مورد API Gateway Resource، والذي يقبل الطلبات على المسار /graphql.

GraphQLApiResource:
  Type: 'AWS::ApiGateway::Resource'
  Properties:
    ParentId: !GetAtt GraphQLApi.RootResourceId
    RestApiId: !Ref GraphQLApi
    PathPart: 'graphql'

بعد ذلك، نقوم بتكوين المورد لقبول طلبات POST عن طريق إنشاء API Gateway Method ثم ندمجه مع Lambda.

GraphQLApiMethod:
  Type: 'AWS::ApiGateway::Method'
  Properties:
    RestApiId: !Ref GraphQLApi
    ResourceId: !Ref GraphQLApiResource
    AuthorizationType: None
    HttpMethod: POST
    Integration:
      Type: AWS_PROXY
      IntegrationHttpMethod: POST
      Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations

أخيرًا، نقوم بإنشاء API Gateway Deployment الذي ينشر الواجهة البرمجية إلى المرحلة المحددة (stage).

GraphQLApiDeployment:
  Type: 'AWS::ApiGateway::Deployment'
  Properties:
    RestApiId: !Ref GraphQLApi
    StageName: v1
  DependsOn:
    - GraphQLApiResource
    - GraphQLApiMethod

أذونات Lambda / API Gateway

في هذه المرحلة، قمنا بتكوين كل من دالة Lambda و API Gateway بشكل صحيح. ومع ذلك، يحتاج API Gateway إلى إذن خاص لاستدعاء دالة Lambda. نسمح لـ API Gateway باستدعاء Lambda عن طريق إنشاء مورد Lambda Permission.

GraphQLApiPermission:
  Type: 'AWS::Lambda::Permission'
  Properties:
    Action: lambda:invokeFunction
    FunctionName: !GetAtt LambdaFunction.Arn
    Principal: apigateway.amazonaws.com
    SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${GraphQLApi}/*

أخيرًا، نقوم بتصدير عنوان URL الخاص بالواجهة البرمجية في نهاية القالب. يمكننا استخدام هذا العنوان لاستدعاء دالة Lambda.

Outputs:
  ApiUrl:
    Description: Invoke url of API Gateway endpoint
    Value: !Sub https://${GraphQLApi}.execute-api.${AWS::Region}.amazonaws.com/v1/graphql

نشر حزمة CloudFormation إلى AWS

الآن بعد أن أصبح قالب CloudFormation جاهزًا، دعنا نستخدم أمر AWS CLI لنشره على AWS. قم بتشغيل الأمر التالي في سطر الأوامر الخاص بك. تأكد من تحديث قيمة BucketName إلى اسم السلة التي أنشأتها سابقًا.

aws cloudformation deploy \
  --template-file ./cloudformation.yml \
  --stack-name apollo-server-lambda-nodejs \
  --parameter-overrides BucketName=lambda-deploy-asln Version=latest \
  --capabilities CAPABILITY_IAM

نشر حزمة CloudFormation إلى AWS

قد يستغرق نشر الحزمة بعض الوقت. يجب أن تكون دالة Lambda جاهزة لبدء تلقي الطلبات عند الانتهاء من النشر.

التحقق من عمل API Gateway و Lambda كما هو متوقع

الآن بعد أن قمنا بنشر حزمة CloudFormation الخاصة بنا، دعنا نتحقق مما إذا كان كل شيء يعمل كما هو متوقع. نحتاج إلى عنوان URL الخاص بـ API Gateway لإرسال طلب إلى دالة Lambda الخاصة بنا. يأتي عنوان URL الخاص بالواجهة البرمجية الذي قمنا بتصديره في قالب CloudFormation مفيدًا هنا. قم بتشغيل الأمر التالي لطباعة عنوان URL الخاص بالواجهة البرمجية في سطر الأوامر.

aws cloudformation describe-stacks \
  --stack-name=apollo-server-lambda-nodejs \
  --query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" \
  --output text

وصف حزمة CloudFormation واستخراج عنوان URL

الآن، استخدم أمر curl لاستدعاء عنوان URL الخاص بالواجهة البرمجية. يجب أن تحصل على Hello from Lambda مرة أخرى من الخادم.

curl -d '{}' https://o55ybz0sc5.execute-api.us-east-1.amazonaws.com/v1/graphql

استدعاء دالة AWS Lambda عبر API Gateway

إضافة سكريبت النشر لتسهيل العملية

ربما لاحظت أننا قمنا بتشغيل مجموعة كاملة من الأوامر لتعبئة ونشر تطبيقنا. سيكون من الممل جدًا تشغيل هذه الأوامر في كل مرة نقوم فيها بنشر التطبيق. دعنا نضيف سكريبت bash لتبسيط سير العمل هذا.

أنشئ دليلًا يسمى bin في جذر التطبيق وأضف ملفًا باسم deploy.

mkdir bin
touch bin/deploy

قبل أن نتمكن من تنفيذ السكريبت، نحتاج إلى تعيين أذونات الملف الصحيحة. دعنا نفعل ذلك عن طريق تشغيل الأمر التالي.

chmod +x bin/deploy

إنشاء سكريبت النشر في مجلد bin

في هذه المرحلة، يجب أن تبدو بنية الدليل لدينا كما في لقطة الشاشة أدناه.

بنية الدليل الحالية للمشروع

أضف الكود التالي إلى الملف:

#!/bin/bash
set -euo pipefail

OUTPUT_DIR=dist
CURRENT_DIR=$(pwd)
ROOT_DIR="$(dirname "${BASH_SOURCE[0]}")"/..
APP_VERSION=$(date +%s)
STACK_NAME=apollo-server-lambda-nodejs

cd $ROOT_DIR

echo "cleaning up old build.."
[ -d $OUTPUT_DIR ] && rm -rf $OUTPUT_DIR
mkdir dist

echo "zipping source code.."
zip -rq $OUTPUT_DIR/dist-$APP_VERSION.zip src node_modules package.json

echo "uploading source code to s3.."
aws s3 cp $OUTPUT_DIR/dist-$APP_VERSION.zip s3://$S3_BUCKET/dist-$APP_VERSION.zip

echo "deploying application.."
aws cloudformation deploy \
  --template-file $ROOT_DIR/cloudformation.yml \
  --stack-name $STACK_NAME \
  --parameter-overrides Version=$APP_VERSION BucketName=$S3_BUCKET \
  --capabilities CAPABILITY_IAM

# Get the api url from output of cloudformation stack
API_URL=$(aws cloudformation describe-stacks \
  --stack-name=$STACK_NAME \
  --query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" \
  --output text)

echo -e "\n$API_URL"

cd $CURRENT_DIR

حسنًا، دعنا نحلل ما يحدث في هذا السكريبت. نبدأ بتعريف بعض المتغيرات. نقوم بإنشاء ملف الأرشيف داخل دليل dist. نحدد إصدار التطبيق ليكون الطابع الزمني الحالي الذي يتم فيه تشغيل السكريبت. باستخدام الطابع الزمني، يمكننا التأكد من أن رقم الإصدار فريد ومتزايد دائمًا.

#!/bin/bash
set -euo pipefail

OUTPUT_DIR=dist
CURRENT_DIR=$(pwd)
ROOT_DIR="$(dirname "${BASH_SOURCE[0]}")"/..
APP_VERSION=$(date +%s)
STACK_NAME=apollo-server-lambda-nodejs

ثم نقوم بتنظيف أي إصدارات قديمة وإنشاء دليل dist جديد.

echo "cleaning up old build.."
[ -d $OUTPUT_DIR ] && rm -rf $OUTPUT_DIR
mkdir dist

بعد ذلك، نقوم بتشغيل أمر zip لأرشفة الكود المصدري وتبعياته.

echo "zipping source code.."
zip -rq $OUTPUT_DIR/dist-$APP_VERSION.zip src node_modules package.json

بعد ذلك، ننسخ ملف zip إلى سلة S3.

echo "uploading source code to s3.."
aws s3 cp $OUTPUT_DIR/dist-$APP_VERSION.zip s3://$S3_BUCKET/dist-$APP_VERSION.zip

ثم نقوم بنشر حزمة CloudFormation.

echo "deploying application.."
aws cloudformation deploy \
  --template-file $ROOT_DIR/cloudformation.yml \
  --stack-name $STACK_NAME \
  --parameter-overrides Version=$APP_VERSION BucketName=$S3_BUCKET \
  --capabilities CAPABILITY_IAM

أخيرًا، نستعلم حزمة CloudFormation للحصول على عنوان URL الخاص بالواجهة البرمجية من مخرجات CloudFormation ونطبعه في سطر الأوامر.

# Get the api url from output of cloudformation stack
API_URL=$(aws cloudformation describe-stacks \
  --stack-name=$STACK_NAME \
  --query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" \
  --output text)

echo -e "\n$API_URL"

النشر إلى AWS باستخدام سكريبت النشر

دعنا نجرب النشر باستخدام سكريبت النشر. يتوقع السكريبت وجود متغير البيئة S3_BUCKET. قم بتشغيل الأمر التالي لتشغيل النشر. عندما ينجح النشر، سيقوم السكريبت بإخراج عنوان URL الخاص بالواجهة البرمجية الذي يمكننا استخدامه لاستدعاء دالة Lambda.

S3_BUCKET=lambda-deploy-asln ./bin/deploy

تشغيل سكريبت النشر لـ AWS Lambda

لتبسيط هذا أكثر، دعنا نستدعيه باستخدام yarn. أضف ما يلي في ملف package.json الخاص بك.

"scripts": {
  "deploy": "S3_BUCKET=lambda-deploy-asln ./bin/deploy"
}

بعد ذلك، يمكننا ببساطة تشغيل yarn deploy لبدء عمليات النشر.

تحسين سير العمل باستخدام Lambda و API Gateway المحليين

غالبًا ما نقوم بتعديل كود التطبيق أثناء العمل على تطبيقنا. حاليًا، يستغرق النشر إلى منطقة AWS us-east-1 حوالي 10 ثوانٍ بالنسبة لي، على اتصال إنترنت بسرعة تحميل 40 ميجابت/ثانية. يصبح وقت النشر أكثر أهمية مع نمو حجم التطبيق. الانتظار لمدة 10 ثوانٍ أو أكثر لإدراك أنني ارتكبت خطأً في بناء الجملة ليس منتجًا على الإطلاق. دعنا نصلح هذا عن طريق إعداد دالة Lambda محليًا واستدعائها باستخدام نقطة نهاية API محلية. يُمكّننا AWS SAM CLI من فعل ذلك تمامًا. اتبع التعليمات في هذه الصفحة لتثبيته. بمجرد الانتهاء، من جذر المشروع، قم بتشغيل الأمر التالي.

sam local start-api --template-file cloudformation.yml

بدء خادم التطوير المحلي باستخدام AWS SAM CLI

نقطة النهاية المحلية متاحة الآن على http://localhost:3000. يمكننا استخدام نقطة النهاية هذه لإرسال طلبات إلى دالة Lambda المحلية الخاصة بنا. افتح طرفية أخرى وقم بتشغيل الأمر التالي لإرسال طلب. يجب أن ترى الاستجابة من دالة Lambda المحلية الخاصة بنا.

curl -d '{}' http://localhost:3000/graphql

استدعاء دالة Lambda المحلية

أخيرًا، أضف الأسطر التالية في قسم scripts في ملف package.json.

"dev": "sam local start-api --template-file cloudformation.yml"

بعد ذلك، يمكننا تشغيل الأمر yarn dev لبدء خادم التطوير.

إعداد خادم GraphQL في Lambda

دون مزيد من الحديث، دعنا ننتقل مباشرة إلى الكود ونبني خادم GraphQL. ابدأ بتثبيت التبعيات. نستخدم Apollo Server لبناء خادم GraphQL الخاص بنا. Apollo Server هو تطبيق مفتوح المصدر لخادم GraphQL.

yarn add apollo-server-lambda graphql

استبدل محتوى ملف src/index.js بالكود التالي:

const { ApolloServer, gql } = require('apollo-server-lambda');

const typeDefs = gql`
  type Query {
    user: User
  }

  type User {
    id: ID
    name: String
  }
`;

const resolvers = {
  Query: {
    user: () => ({ id: 123, name: 'John Doe' })
  }
};

const server = new ApolloServer({ typeDefs, resolvers });

exports.handler = server.createHandler();

هنا، نحدد مخططًا (schema) يتكون من نوع User واستعلام user. ثم نحدد محللًا (resolver) لاستعلام user. من أجل التبسيط، يقوم المحلل بإرجاع مستخدم ثابت البيانات. أخيرًا، نقوم بإنشاء معالج GraphQL وتصديره.

لإجراء استعلامات على خادم GraphQL الخاص بنا، نحتاج إلى عميل GraphQL. Insomnia هو العميل المفضل لدي، ولكن أي عميل GraphQL آخر سيكون جيدًا. الآن، دعنا نجري استعلامًا للتأكد من أن خادمنا يعمل كما هو متوقع. أنشئ طلب GraphQL جديدًا في Insomnia.

إنشاء طلب GraphQL جديد في Insomnia
تكوين طلب GraphQL في Insomnia

أضف الاستعلام التالي في الجسم وأرسل الاستعلام إلى http://localhost:3000. بافتراض أن خادم التطوير الخاص بك لا يزال قيد التشغيل، يجب أن ترى الاستجابة التالية من خادم GraphQL.

تنفيذ طلب GraphQL على الخادم المحلي

الآن بعد أن تحققنا من أن كل شيء يعمل بشكل جيد في الخادم المحلي، دعنا نشغل الأمر التالي لنشر خادم GraphQL إلى AWS.

yarn deploy

نشر خادم GraphQL إلى AWS

يتم إخراج عنوان URL الخاص بالواجهة البرمجية في سطر الأوامر بمجرد اكتمال النشر. استبدل عنوان URL في Insomnia بالذي حصلت عليه من API Gateway. أعد تشغيل الاستعلام لترى أنه يتم حله.

تنفيذ طلب GraphQL على AWS Lambda

الخلاصة التقنية

تهانينا! لقد نجحت في نشر خادم GraphQL على AWS Lambda بالكامل باستخدام CloudFormation. هذا الإنجاز يمثل خطوة مهمة نحو بناء تطبيقات حديثة وقابلة للتوسع. لقد أظهرنا كيف يمكن لخادمك استقبال طلبات GraphQL من العميل وإرجاع الاستجابات المناسبة بكفاءة عالية. الأهم من ذلك، قمنا بإعداد بيئة تطوير محلية قوية باستخدام AWS SAM CLI، مما يقلل بشكل كبير من أوقات الانتظار ويزيد من إنتاجية المطورين، دون الحاجة إلى إضافة الكثير من التبعيات المعقدة. هذا النهج يضمن دورة تطوير سريعة وفعالة، ويؤكد على قوة دمج التقنيات السحابية الحديثة مع أنماط الواجهات البرمجية المرنة.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *