Лучший подход к обработке graphql для aws lambda?

Я следую руководству https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers.html

И есть некоторые сомнения в использовании только switch для обработки запросов graphql.

Есть ли лучший подход для обработки более сложных запросов?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
1 146
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете проксировать все запросы на graphql-сервер

Сервер Apollo GraphQL обеспечивает очень хорошую настройку для развертывания сервера GraphQL в AWS Lambda.

Я использовал этот подход, и он мне очень помог. apollo-server-lambda предоставляет функцию createHandler, которая соответствует подписи, необходимой для AWS Lambda.

user2688473 19.02.2019 08:14

Вам не нужно использовать одну AWS Lambda для обработки каждого запроса. Новичкам легче понять это руководство, поэтому они использовали этот подход.

Но как это реализовать в конце - решать вам. В качестве альтернативы можно было бы создать для каждого распознавателя отдельную AWS Lambda, чтобы исключить switch и следовать Принцип единой ответственности (SRP).

Да, конечная точка остается прежней. Просто AWS Lambda за резолвером отличается.

MaiKaY 17.07.2018 15:28

Это противоречит цели graphql: сервер GraphQL работает с одним URL / конечной точкой

Gabriel Bleu 17.07.2018 15:33

@GabrielBleu лямбда не является сервером GraphQL - AppSync предоставляет реализацию GraphQL - лямбда используется преобразователем для заполнения одного поля в API. Использование разных лямбда-выражений для разных полей в API вполне разумно (они могут работать с очень разными ресурсами для разрешения данных, например, или иметь разные требования к вычислениям / памяти).

macbutch 17.07.2018 15:37

@GabrielBleu Вы должны проверить технический документ AWS AppSync.

MaiKaY 17.07.2018 15:41

Хорошо, вы используете несколько лямбда-выражений для преобразователей за одной конечной точкой. Следите за тем, чтобы не разделять слишком много или менее используемых лямбд, всегда будет холодный старт.

Gabriel Bleu 17.07.2018 16:00
Ответ принят как подходящий

Выбор за вами, как настроить лямбда-выражение в API AppSync. Вполне разумно иметь лямбда-функцию для каждого преобразователя и иметь функцию, отвечающую за один преобразователь. В качестве альтернативы вы можете воспользоваться подходом, подобным учебному руководству, и использовать одну функцию и небольшой код маршрутизации, чтобы позаботиться о вызове правильной функции. Использование одной функции часто может дать некоторые преимущества в производительности из-за того, как работает подогрев контейнера лямбда (особенно для Java и C#, где время запуска виртуальной машины может складываться), но имеет меньшее разделение проблем.

Вот несколько подходов, которые я использовал в прошлом:

Вариант 1: JS

Этот подход использует JavaScript и должен быть знаком тем, кто раньше запускал свои собственные серверы GraphQL.

const Resolvers = {
  Query: {
    me: (source, args, identity) => getLoggedInUser(args, identity)
  },
  Mutation: {
    login: (source, args, identity) => loginUser(args, identity)
  }
}

exports.handler = (event, context, callback) => {
    // We are going to wire up the resolver to give all this information in this format.
    const { TypeName, FieldName, Identity, Arguments, Source } = event

    const typeResolver = Resolvers[TypeName]
    if (!typeResolver) {
      return callback(new Error(`No resolvers found for type: "${TypeName}"`))
    }
    const fieldResolver = typeResolver[FieldName]
    if (!fieldResolver) {
      return callback(new Error(`No resolvers found for field: "${FieldName}" on type: "${TypeName}"`), null)
    }
    // Handle promises as necessary.
    const result = fieldResolver(Source, Arguments, Identity);
    return callback(null, result)
};

Затем вы можете использовать стандартный лямбда-преобразователь из AppSync. На данный момент мы должны указать TypeName и FieldName вручную.

#**
    The value of 'payload' after the template has been evaluated
    will be passed as the event to AWS Lambda.
*#
{
    "version" : "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "TypeName": "Query",
        "FieldName": "me",
        "Arguments": $util.toJson($context.arguments),
        "Identity": $util.toJson($context.identity),
        "Source": $util.toJson($context.source)
    }
}

Вариант 2: Перейти

Для любопытных я также успешно использовал лямбда-функции go с AppSync. Вот один подход, который мне хорошо сработал.

package main

import (
  "context"
  "fmt"

  "github.com/aws/aws-lambda-go/lambda"
  "github.com/fatih/structs"
  "github.com/mitchellh/mapstructure"
)

type GraphQLPayload struct {
  TypeName    string                 `json:"TypeName"`
  FieldName   string                 `json:"FieldName"`
  Arguments   map[string]interface{} `json:"Arguments"`
  Source      map[string]interface{} `json:"Source"`
  Identity    map[string]interface{} `json:"Identity"`
}

type ResolverFunction func(source, args, identity map[string]interface{}) (data map[string]interface{}, err error)

type TypeResolverMap = map[string]ResolverFunction

type SchemaResolverMap = map[string]TypeResolverMap

func resolverMap() SchemaResolverMap {
  return map[string]TypeResolverMap{
    "Query": map[string]ResolverFunction{
      "me": getLoggedInUser,
    },
  }
}

func Handler(ctx context.Context, event GraphQLPayload) (map[string]interface{}, error) {
  // Almost the same as the JS option.
  resolvers := resolverMap()
  typeResolver := resolvers[event.TypeName]
  if typeResolver == nil {
    return nil, fmt.Errorf("No type resolver for type " + event.TypeName)
  }
  fieldResolver := typeResolver[event.FieldName]
  if fieldResolver == nil {
    return nil, fmt.Errorf("No field resolver for field " + event.FieldName)
  }
  return fieldResolver(event.Source, event.Arguments, event.Identity)
}

func main() {
  lambda.Start(Handler)
}

/**
* Resolver Functions
 */

/**
 * Get the logged in user
 */
func getLoggedInUser(source, args, identity map[string]interface{}) (data map[string]interface{}, err error) {

  // Decode the map[string]interface{} into a struct I defined
  var typedArgs myModelPackage.GetLoggedInUserArgs
  err = mapstructure.Decode(args, &typedArgs)
  if err != nil {
    return nil, err
  }

  // ... do work
  res, err := auth.GetLoggedInUser()
  if err != nil {
    return nil, err
  }

  // Map the struct back to a map[string]interface{}
  return structs.Map(out), nil
}

// ... Add as many more as needed

Затем вы можете использовать тот же шаблон преобразователя, что и в варианте 1. Есть много других способов сделать это, но это один метод, который хорошо сработал для меня.

Надеюсь это поможет :)

Другие вопросы по теме