如何在Golang中将多个Lambda函数接入统一Reservations API?
实现统一Reservations API分发CRUD请求的方案
针对你的需求,这里提供两种适配你技术栈的实现方式,分别对应REST风格统一端点和GraphQL原生统一入口:
方案一:REST风格统一HTTP端点
通过一个/reservations POST端点,解析请求体中的操作类型字段,分发到对应CRUD函数:
1. 定义通用请求结构体
先定义包含操作类型和业务数据的请求结构:
package main import ( "encoding/json" "log" "net/http" ) // Reservation 预订数据结构 type Reservation struct { ID string `json:"id"` RoomID string `json:"room_id"` GuestName string `json:"guest_name"` // 补充你需要的其他字段 } // ReservationRequest 统一请求结构体 type ReservationRequest struct { Action string `json:"action"` // 取值为create/delete/update/get ReservationData Reservation `json:"data"` }
2. 实现CRUD业务函数
保留你已有的CRUD逻辑,封装为独立函数:
// createReservation 创建预订 func createReservation(data Reservation) error { // 这里写入你的DynamoDB创建逻辑 log.Printf("创建预订: %+v", data) return nil } // deleteReservation 删除预订 func deleteReservation(data Reservation) error { // 这里写入你的DynamoDB删除逻辑 log.Printf("删除预订ID: %s", data.ID) return nil } // updateReservation 更新预订 func updateReservation(data Reservation) error { // 这里写入你的DynamoDB更新逻辑 log.Printf("更新预订: %+v", data) return nil } // getReservation 查询预订 func getReservation(data Reservation) (*Reservation, error) { // 这里写入你的DynamoDB查询逻辑 res := Reservation{ID: data.ID, RoomID: "R101", GuestName: "测试用户"} log.Printf("查询预订ID: %s", data.ID) return &res, nil }
3. 统一处理函数与路由注册
在main.go中注册统一路由,通过switch分发请求:
func reservationsHandler(w http.ResponseWriter, r *http.Request) { // 限制仅POST方法访问 if r.Method != http.MethodPost { http.Error(w, "仅支持POST请求", http.StatusMethodNotAllowed) return } // 解析请求体 var req ReservationRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "请求格式错误", http.StatusBadRequest) return } // 根据Action分发到对应CRUD函数 var resp interface{} var err error switch req.Action { case "create": err = createReservation(req.ReservationData) resp = map[string]string{"status": "创建成功"} case "delete": err = deleteReservation(req.ReservationData) resp = map[string]string{"status": "删除成功"} case "update": err = updateReservation(req.ReservationData) resp = map[string]string{"status": "更新成功"} case "get": resp, err = getReservation(req.ReservationData) default: http.Error(w, "未知操作类型", http.StatusBadRequest) return } // 处理错误响应 if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // 返回成功响应 w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(resp) } func main() { // 注册统一API路由 http.HandleFunc("/reservations", reservationsHandler) log.Println("服务启动在 :8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
方案二:GraphQL原生统一入口
由于你已经使用GraphQL技术栈,更推荐这种方式——通过GraphQL的单一入口,定义包含所有CRUD操作的Mutation和Query类型:
1. 定义GraphQL Schema
package main import ( "context" "encoding/json" "log" "net/http" "github.com/graphql-go/graphql" ) // Reservation 预订数据结构 type Reservation struct { ID string `json:"id"` RoomID string `json:"roomId"` GuestName string `json:"guestName"` } // 定义GraphQL类型 var reservationType = graphql.NewObject( graphql.ObjectConfig{ Name: "Reservation", Fields: graphql.Fields{ "id": &graphql.Field{Type: graphql.ID}, "roomId": &graphql.Field{Type: graphql.String}, "guestName": &graphql.Field{Type: graphql.String}, }, }, )
2. 实现Resolver函数
对应每个CRUD操作编写Resolver,关联你的DynamoDB逻辑:
// Resolver 处理GraphQL请求的解析器 type Resolver struct{} // CreateReservation 创建预订的Resolver func (r *Resolver) CreateReservation(ctx context.Context, args struct { RoomID string GuestName string }) (*Reservation, error) { // 调用DynamoDB创建逻辑 res := &Reservation{ ID: "res-" + args.RoomID, // 示例ID生成逻辑 RoomID: args.RoomID, GuestName: args.GuestName, } log.Printf("创建预订: %+v", res) return res, nil } // DeleteReservation 删除预订的Resolver func (r *Resolver) DeleteReservation(ctx context.Context, args struct{ ID string }) (bool, error) { // 调用DynamoDB删除逻辑 log.Printf("删除预订ID: %s", args.ID) return true, nil } // UpdateReservation 更新预订的Resolver func (r *Resolver) UpdateReservation(ctx context.Context, args struct { ID string GuestName *string }) (*Reservation, error) { // 调用DynamoDB更新逻辑 res := &Reservation{ID: args.ID, RoomID: "R101", GuestName: *args.GuestName} log.Printf("更新预订: %+v", res) return res, nil } // GetReservation 查询预订的Resolver func (r *Resolver) GetReservation(ctx context.Context, args struct{ ID string }) (*Reservation, error) { // 调用DynamoDB查询逻辑 res := &Reservation{ID: args.ID, RoomID: "R101", GuestName: "测试用户"} log.Printf("查询预订ID: %s", args.ID) return res, nil }
3. 构建Schema并注册路由
func main() { // 构建GraphQL Schema schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: graphql.NewObject(graphql.ObjectConfig{ Name: "Query", Fields: graphql.Fields{ "getReservation": &graphql.Field{ Type: reservationType, Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.ID)}, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { args := struct{ ID string }{ID: p.Args["id"].(string)} return (&Resolver{}).GetReservation(p.Context, args) }, }, }, }), Mutation: graphql.NewObject(graphql.ObjectConfig{ Name: "Mutation", Fields: graphql.Fields{ "createReservation": &graphql.Field{ Type: reservationType, Args: graphql.FieldConfigArgument{ "roomId": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)}, "guestName": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)}, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { args := struct { RoomID string GuestName string }{ RoomID: p.Args["roomId"].(string), GuestName: p.Args["guestName"].(string), } return (&Resolver{}).CreateReservation(p.Context, args) }, }, "deleteReservation": &graphql.Field{ Type: graphql.Boolean, Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.ID)}, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { args := struct{ ID string }{ID: p.Args["id"].(string)} return (&Resolver{}).DeleteReservation(p.Context, args) }, }, "updateReservation": &graphql.Field{ Type: reservationType, Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.ID)}, "guestName": &graphql.ArgumentConfig{Type: graphql.String}, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { guestName, _ := p.Args["guestName"].(*string) args := struct { ID string GuestName *string }{ ID: p.Args["id"].(string), GuestName: guestName, } return (&Resolver{}).UpdateReservation(p.Context, args) }, }, }, }), }) if err != nil { log.Fatalf("Schema构建失败: %v", err) } // 注册GraphQL统一入口路由 http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) { query := r.FormValue("query") result := graphql.Do(graphql.Params{ Schema: schema, RequestString: query, Context: r.Context(), }) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(result) }) log.Println("GraphQL服务启动在 :8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
使用示例
发送GraphQL请求到/graphql,比如创建预订的请求:
mutation { createReservation(roomId: "R101", guestName: "张三") { id roomId guestName } }
内容的提问来源于stack exchange,提问作者Tharun Raj
相关产品推荐
相关产品推荐

