簡體   English   中英

為AWS Lambda處理graphql的最佳方法?

[英]Best approach to handle graphql for aws lambda?

我正在關注教程https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers.html

對於僅使用switch來處理graphql查詢,還有一些疑問。

有沒有更好的方法來處理更復雜的請求?

由您決定如何在AppSync API中設置lambda。 每個解析器都具有lambda函數並由一個函數負責單個解析器是完全合理的。 您也可以采用類似於本教程的方法,並使用單個函數和一些輕量級路由代碼來照顧正確的函數。 由於lambda的容器預熱如何工作(尤其是Java和C#,VM啟動時間可能加起來),因此使用單個函數通常可以帶來一些性能上的好處,但關注點之間的分離卻較少。

這是我過去采用的一些方法:

選項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中的標准lambda解析器。 現在,我們必須手動提供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:執行

出於好奇,我還通過AppSync成功使用了go lambda函數。 這是一種對我有效的方法。

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中使用的相同的解析器模板。還有許多其他方法可以執行此操作,但這是一種對我有效的方法。

希望這可以幫助 :)

您沒有被迫使用單個AWS Lambda來處理每個請求。 對於本教程,新手更容易理解它,因此他們使用了這種方法。

但是最終由您自己決定如何實施。 一種替代方法是為每個解析器創建一個單獨的AWS Lambda,以消除該switch並遵循單一職責原則(SRP)

您可以將所有查詢代理到graphql服務器

Apollo GraphQL Server提供了一個非常好的設置,可以在AWS Lambda中部署GraphQL服務器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM