이번 주에 내가 무엇을 배웠습니까?

Golang에서 GraphQL을 구현하는 방법이 궁금합니다. 검색을 시도하고 도움이 될 라이브러리를 찾았습니다. 목록은 다음과 같습니다.

  • graphql-go . GraphQL을 구현하는 데 도움이 되도록 이것을 사용합니다.

  • echo . 이 라이브러리를 사용하여 라우팅 및 HTTP 처리기를 구현하는 데 도움을 받습니다.

  • gorm . 저는 이 라이브러리를 사용하여 데이터베이스 쪽을 구현하는 데 도움을 줍니다. 이 라이브러리는 ORM입니다.

  • 코드 ???



    내 Github 저장소를 방문하는 것이 좋습니다.


    bervProject / go-마이크로서비스-보일러플레이트


    Go 마이크로서비스 상용구





    go-마이크로서비스-보일러플레이트


    Go 마이크로서비스 상용구

    특허


    MIT



    View on GitHub



    코드는 다음과 같습니다.

    package main
    
    import (
        "database/sql"
        "fmt"
        "log"
        "net/http"
        "os"
        "time"
    
        "github.com/graphql-go/graphql"
        "github.com/labstack/echo/v4"
        "gorm.io/driver/postgres"
        "gorm.io/gorm"
    )
    
    type PostData struct {
        Query     string                 `json:"query"`
        Operation string                 `json:"operation"`
        Variables map[string]interface{} `json:"variables"`
    }
    
    type User struct {
        ID           uint
        Name         string
        Email        *string
        Age          uint8
        Birthday     *time.Time
        MemberNumber sql.NullString
        ActivatedAt  sql.NullTime
        CreatedAt    time.Time
        UpdatedAt    time.Time
    }
    
    func executeQuery(query string, schema graphql.Schema) *graphql.Result {
        result := graphql.Do(graphql.Params{
            Schema:        schema,
            RequestString: query,
        })
        if len(result.Errors) > 0 {
            fmt.Printf("wrong result, unexpected errors: %v", result.Errors)
        }
        return result
    }
    
    func main() {
        dsn := os.Getenv("DB_CONNECTION_STRING")
        db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
        if err != nil {
            log.Fatalf("failed to connect database, error: %v", err)
        }
        db.AutoMigrate(&User{})
        // Schema
        userType := graphql.NewObject(
            graphql.ObjectConfig{
                Name: "User",
                Fields: graphql.Fields{
                    "id": &graphql.Field{
                        Type: graphql.Int,
                    },
                    "name": &graphql.Field{
                        Type: graphql.String,
                    },
                },
            },
        )
    
        fields := graphql.Fields{
            "hello": &graphql.Field{
                Type: graphql.String,
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    return "world", nil
                },
            },
        }
        mutationFields := graphql.Fields{
            "createUser": &graphql.Field{
                Type:        userType,
                Description: "Create New User",
                Args: graphql.FieldConfigArgument{
                    "name": &graphql.ArgumentConfig{
                        Type: graphql.NewNonNull(graphql.String),
                    },
                },
                Resolve: func(params graphql.ResolveParams) (interface{}, error) {
                    user := User{
                        Name: params.Args["name"].(string),
                    }
                    result := db.Create(&user)
                    if result.Error != nil {
                        return nil, result.Error
                    }
                    return user, nil
                },
            },
        }
        rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
        rootMutation := graphql.ObjectConfig{Name: "RootMutation", Fields: mutationFields}
        schemaConfig := graphql.SchemaConfig{
            Query:    graphql.NewObject(rootQuery),
            Mutation: graphql.NewObject(rootMutation),
        }
        schema, err := graphql.NewSchema(schemaConfig)
        if err != nil {
            log.Fatalf("failed to create new schema, error: %v", err)
        }
        e := echo.New()
        e.GET("/", func(c echo.Context) error {
            return c.String(http.StatusOK, "Hello, World!")
        })
        e.POST("/graphql", func(c echo.Context) error {
            data := new(PostData)
            if err := c.Bind(data); err != nil {
                return err
            }
            result := graphql.Do(graphql.Params{
                Schema:         schema,
                RequestString:  data.Query,
                VariableValues: data.Variables,
                OperationName:  data.Operation,
            })
            return c.JSON(http.StatusOK, result)
        })
        e.Logger.Fatal(e.Start(":1323"))
    }
    

    TLDR


    중요 부품



    우리는 3개의 중요한 부분을 가질 것입니다. 갑시다.
  • Echo를 시작하고 GraphQL 경로 및 공통 실행을 정의하여 GraphQL Query 또는 GraphQL Mutation을 호출합니다.

  • // data struct to represent the request of GraphQL.
    type PostData struct {
        Query     string                 `json:"query"`
        Operation string                 `json:"operation"`
        Variables map[string]interface{} `json:"variables"`
    }
    
    func main() {
      // ... rest of codes
    
      // initiate echo
      e := echo.New()
    
      // initiate path and handler
      e.POST("/graphql", func(c echo.Context) error {
            // bind body message of query/mutation to PostData
        data := new(PostData)
        if err := c.Bind(data); err != nil {
            return err
        }
            // call the graphql using the data provided and already binded with PostData
        result := graphql.Do(graphql.Params{
            Schema:         schema,
            RequestString:  data.Query,
            VariableValues: data.Variables,
            OperationName:  data.Operation,
        })
            // return the result as it is and expect will success
            // we will learn in the next post about error handling
        return c.JSON(http.StatusOK, result)
      })
        e.Logger.Fatal(e.Start(":1323"))
    }
    

  • 데이터베이스 및 ORM 시작

  • // sample table definition
    type User struct {
        ID           uint
        Name         string
        Email        *string
        Age          uint8
        Birthday     *time.Time
        MemberNumber sql.NullString
        ActivatedAt  sql.NullTime
        CreatedAt    time.Time
        UpdatedAt    time.Time
    }
    
    
    func main() {
            // you may change the os.Getenv to string directly for testing in case you don't have the env.
            dsn := os.Getenv("DB_CONNECTION_STRING")
            // initiate the database connection
            // since I use postgres, so the open come from postgres driver, you may use other drivers if you are using another database.
        db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
        if err != nil {
            log.Fatalf("failed to connect database, error: %v", err)
        }
            // we are doing auto migrate
        db.AutoMigrate(&User{})
            // ... rest of codes
    }
    

  • GraphQL 스키마, 쿼리 및 변형 시작

  • func main() {
           // ... rest of codes
    
          // initiate user object
            userType := graphql.NewObject(
            graphql.ObjectConfig{
                Name: "User",
                Fields: graphql.Fields{
                    "id": &graphql.Field{
                        Type: graphql.Int,
                    },
                    "name": &graphql.Field{
                        Type: graphql.String,
                    },
                },
            },
        )
    
            // sample to define queries
        fields := graphql.Fields{
            "hello": &graphql.Field{
                Type: graphql.String,
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    return "world", nil
                },
            },
        }
            // sample to define mutations
        mutationFields := graphql.Fields{
            "createUser": &graphql.Field{
                Type:        userType,
                Description: "Create New User",
                Args: graphql.FieldConfigArgument{
                    "name": &graphql.ArgumentConfig{
                        Type: graphql.NewNonNull(graphql.String),
                    },
                },
                Resolve: func(params graphql.ResolveParams) (interface{}, error) {
                    user := User{
                        Name: params.Args["name"].(string),
                    }
                    result := db.Create(&user)
                    if result.Error != nil {
                        return nil, result.Error
                    }
                    return user, nil
                },
            },
        }
            // merge the queries into rootQuery
        rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
            // merge the mutation into rootMutation
        rootMutation := graphql.ObjectConfig{Name: "RootMutation", Fields: mutationFields}
            // merge query & mutation to 1 schema
        schemaConfig := graphql.SchemaConfig{
            Query:    graphql.NewObject(rootQuery),
            Mutation: graphql.NewObject(rootMutation),
        }
            // initiate the schema
        schema, err := graphql.NewSchema(schemaConfig)
        if err != nil {
            log.Fatalf("failed to create new schema, error: %v", err)
        }
           // ... rest of codes
    }
    

    고맙습니다



    이번 주에 배운 내용을 공유하고 싶습니다. 특히 GraphQL로 코딩하고 싶다면 go에 대해 많이 배우고 이해하려고 노력합니다. 내 공유를 즐기시기 바랍니다. 질문이 있으시면 알려주세요. 우리는 함께 배울 것입니다. 고맙습니다!


    기타 관련 기사



    이 기사도 보고 싶을 것입니다.







    좋은 웹페이지 즐겨찾기