рдЧреЛрд▓рдВрдЧ рдкрд░ рдПрдХ рдЧреНрд░рд╛рдлрд┐рдХрд▓ рдмреИрдХрдПрдВрдб рдмрдирд╛рдПрдВ

рдЖрдЬ рд╣рдо Golang + GraphQL рдореЗрдВ рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд┐рдХрд╕рд┐рдд рдХрд░реЗрдВрдЧреЗред

рд╣рдо рдЕрдХреНрд╕рд░ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рдЧреНрд░рд╛рдлрдХрд▓рд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд░рддреЗ рд╣реИрдВ: рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рд░реВрдмреА, рдФрд░ рдЕрдм рд╣рдорд╛рд░реЗ рд╣рд╛рде рдЧреЛрд▓рдВрдЧ рдЧреНрд░рд╛рдлрдХрд▓рд╛рдЗрди рдмрдВрдбрд▓ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рдмрд┐рдВрджреБ рдкрд░ рдкрд╣реБрдВрдЪ рдЧрдП рд╣реИрдВред

рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЧреНрд░рд╛рдлрдХреНрдпреВрдПрд▓ рдХреНрд╡реЗрд░реА рднрд╛рд╖рд╛ рдХреЗ рдлрд╛рдпрджреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ, рдХрдИ рд▓реЛрдЧ рдЗрд╕рдХреА рд╕рд░рд▓рддрд╛, рд▓рдЪреАрд▓реЗрдкрди рдФрд░ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╢рдВрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдм рджреЛрдиреЛрдВ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

GraphQL, GraphiQL рдпрд╛ GraphQL Playground рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдЕрдХреНрд╕рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдФрд░ рдПрдкреАрдЖрдИ рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ред
рд╕реНрдерд╛рдиреАрдп рд╕реНрддрд░ рдкрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкреНрд▓реЗрдЧреНрд░рд╛рдЙрдВрдб рдХреЛ рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдЦреБрд▓реЗ рд╕реНрд░реЛрдд рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ - рдЧреНрд░рд╛рдлрд▓-рдЧреЛ рдХреЗ рд▓рд┐рдП рдЧреЛрд▓рдВрдЧ рдПрдЪрдЯреАрд╣реИрдВрдбрд▓рд░ред

рдЧреНрд░реЗрдлреЗрд▓ рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди рдЧреЛрд▓рдВрдЧ

рдпрд╣ рдПрдХ рдЦреЗрд▓ рдХреЗ рдореИрджрд╛рди рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИред

рдЖрдЗрдП рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдЧрд╛ рдХрд┐ рдЧреНрд░рд╛рдлрдХреЙрдХ рдФрд░ рдЧреЛ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рдПред рдкреВрд░рд╛ рдЖрд╡реЗрджрди рдХреЛрдб рдЬреАрдердм рдкрд░ рд▓рд┐рдВрдХ рдкрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╕рд░реНрд╡рд░ рдФрд░ рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗред

func main() {
  schema, err := graphql.NewSchema(defineSchema()) //      
  if err != nil {
     log.Panic("Error when creating the graphQL schema", err)
  }

  h := handler.New(&handler.Config{
     Schema:     &schema,
     Pretty:     true,
     GraphiQL:   false,
     Playground: true,
  }) //      FormatErrorFn -    

  http.Handle("/graphql", h) //      playground    
  err = http.ListenAndServe(":8080", nil)
  if err != nil {
     log.Panic("Error when starting the http server", err)
  }
}

рдХреЛрдИ рднреА рд░реЗрдЦрд╛рдВрдХрди рдмреИрдХрдПрдВрдб рдпреЛрдЬрдирд╛ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рдмрд┐рдирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЕрдм рд╣рдо рдЗрд╕рдХреЗ рд╡рд┐рд╡рд░рдг рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗред

var User = graphql.NewObject(
  graphql.ObjectConfig{
     Name: "User",
     Fields: graphql.Fields{
        "_id": &graphql.Field{
           Type: ObjectID,
        },
        "firstName": &graphql.Field{
           Type: graphql.String,
        },
        "lastName": &graphql.Field{
           Type: graphql.String,
        },
        "email": &graphql.Field{
           Type: graphql.String,
        },
     },
  },
)

var UserInput = graphql.NewInputObject(
  graphql.InputObjectConfig{
     Name: "UserInput",
     Fields: graphql.InputObjectConfigFieldMap{
        "firstName": &graphql.InputObjectFieldConfig{
           Type: graphql.String,
        },
        "lastName": &graphql.InputObjectFieldConfig{
           Type: graphql.Int,
        },
        "email": &graphql.InputObjectFieldConfig{
           Type: graphql.String,
        },
     },
  },
)

func defineSchema() graphql.SchemaConfig {
  return graphql.SchemaConfig{
     Query: graphql.NewObject(graphql.ObjectConfig{
        Name: "Query",
        Fields: graphql.Fields{
           "users": &graphql.Field{
              Name:    "users",
              Type:    graphql.NewList(User),
              Resolve: usersResolver,
           },
        },
     }),
     Mutation: graphql.NewObject(graphql.ObjectConfig{
        Name: "Mutation",
        Fields: graphql.Fields{
           "addUser": &graphql.Field{
              Name:    "addUser",
              Type:    User,
              Resolve: addUserResolver,
              Args: graphql.FieldConfigArgument{
                 "input": &graphql.ArgumentConfig{
                    Type: UserInput,
                 },
              },
           },
        },
     })}
}

рдКрдкрд░, рд╣рдордиреЗ рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдХрд╛рд░ _id, firstName, lastName рдФрд░ рдИрдореЗрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛, рдЬрд┐рд╕реЗ рд╣рдо рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдЬрд╡рд╛рдм рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред _Id рдлрд╝реАрд▓реНрдб рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЬреЛ рдПрдХ рдХрд╕реНрдЯрдо рдкреНрд░рдХрд╛рд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдореВрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдХрд╛рд░ MongoDB рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛, рдЬреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрд░рдЪрдирд╛ рд╣реИред

type InsertOneResult struct {
  InsertedID interface{}
}

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, UserInput рдкреНрд░рдХрд╛рд░ 3 рд╡реИрдХрд▓реНрдкрд┐рдХ рдлрд╝реАрд▓реНрдб рд╕реЗ рдмрдирд╛ рдерд╛ рдЬреЛ рд╣рдорд╛рд░реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдореЗрдВ _id рдлрд╝реАрд▓реНрдб рдЕрдиреБрдкрд╕реНрдерд┐рдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд░рд┐рдЬрд╝реЙрд▓реНрд╡рд░ рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╣реЛрдЧреАред

рдореЛрдВрдЧреЛрдбрдм рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЧреЛрд▓рдВрдЧ рдореЛрдВрдЧреЛрдбрдм рдбреНрд░рд╛рдЗрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред

func usersCollection() *mongo.Collection { // ,   users    
  ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
  client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://mongo:27017"))
  if err != nil {
     log.Panic("Error when creating mongodb connection client", err)
  }
  collection := client.Database("testing").Collection("users")
  err = client.Connect(ctx)
  if err != nil {
     log.Panic("Error when connecting to mongodb", err)
  }

  return collection
}


//      
func usersResolver(_ graphql.ResolveParams) (interface{}, error) {
  ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
  collection := usersCollection()
  result, err := collection.Find(ctx, bson.D{})
  if err != nil {
     log.Print("Error when finding user", err)
     return nil, err
  }

  defer result.Close(ctx)

  var r []bson.M
  err = result.All(ctx, &r)
  if err != nil {
     log.Print("Error when reading users from cursor", err)
  }

  return r, nil
}


//     
func addUserResolver(p graphql.ResolveParams) (interface{}, error) {
  ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
  collection := usersCollection()
  //         ,   _id
  id, err := collection.InsertOne(ctx, p.Args["input"])
  if err != nil {
     log.Print("Error when inserting user", err)
     return nil, err
  }

  var result bson.M
  //       _id
  err = collection.FindOne(ctx, bson.M{"_id": id.InsertedID}).Decode(&result)
  if err != nil {
     log.Print("Error when finding the inserted user by its id", err)
     return nil, err
  }

  return result, nil
}

рдпрд╣рд╛рдВ рд╣рдордиреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдерд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рдореЛрдВрдЧреЙрдбрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдзрд┐рдЧреНрд░рд╣рдг рдФрд░ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ред рдЗрд╕ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рджреЛрдиреЛрдВ рдЧреИрд░-рд╕рдВрдмрдВрдзрдкрд░рдХ рдФрд░ рд╕рдВрдмрдВрдзрдкрд░рдХ, рдХреНрдпреЛрдВрдХрд┐ рдЧреНрд░рд╛рдлрдХреЙрд▓ рд╣рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдЪреБрдирдиреЗ рдореЗрдВ рд╕реАрдорд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдореИрдВрдиреЗ рдЧреЙрд▓рдВрдЧ рдФрд░ рдореЛрдВрдЧреЛрдбрдм рдХреЛ рдмрдВрдбрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбреЙрдХрдЯрд░ рдХрдВрдкреЛрдЬрд╝ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рдЫреЛрдЯреА рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ред рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реИред рдЧреЛрд▓рдВрдЧ рдореЛрдВрдЧреЛ рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпреЛрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рд╣рдореЗрдВ рдЧреНрд░рд╛рдлрд╝рд┐рдХрд▓ рдкреНрд░рд╢реНрдиреЛрдВ рд╕реЗ рд╡рд╛рдкрд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рдХреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред

version: '3'
services:
graphql:
image: golang
volumes:
- .:/go/src
command: /bin/bash -c "cd src && go run *.go"
ports:
- 8080:8080
mongo:
image: mongo





рдмреЗрд╢рдХ, рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛рдлреА рд╕рд░рд▓ рдФрд░ рдХреЙрдореНрдкреИрдХреНрдЯ рдирд┐рдХрд▓рд╛ред рдФрд░ рдЗрд╕реЗ рдЖрдкрдХреА рдЕрдЧрд▓реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдирдП рдкреНрд░рдХрд╛рд░, рдЕрдиреБрд░реЛрдз рдФрд░ рдореНрдпреВрдЯреЗрд╢рди рдФрд░ рдЕрдиреНрдп рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рдкреВрд░рдХ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдмрд╛рд░ рд╣рдордиреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреБрдЫ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдЧреНрд░рд╛рдлрдХреЙрд▓ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛, рд╕рджрд╕реНрдпрддрд╛ред рд╢рд╛рдпрдж рдореИрдВ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдЬрд╛рд░реА рд░рдЦреВрдВрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ рдпрджрд┐ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЖрдкрдХреЗ рд▓рд┐рдП рдХреБрдЫ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рдерд╛ рдФрд░ рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ рд╣рдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред

All Articles