commit af2391cf28be98acca7d8b1b6c8e4e71cea0ba22 Author: Matthieu Lamalle Date: Wed Jul 24 16:52:09 2019 +0200 first issue diff --git a/graphql b/graphql new file mode 100755 index 0000000..49ab348 Binary files /dev/null and b/graphql differ diff --git a/main.go b/main.go new file mode 100644 index 0000000..5c7fe96 --- /dev/null +++ b/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "cadoles/graphql/mutations" + "cadoles/graphql/postgres" + "cadoles/graphql/queries" + "log" + "net/http" + + "github.com/graphql-go/graphql" + "github.com/graphql-go/handler" +) + +func main() { + + schemaConfig := graphql.SchemaConfig{ + Query: graphql.NewObject(graphql.ObjectConfig{ + Name: "RootQuery", + Fields: queries.GetRootFields(), + }), + Mutation: graphql.NewObject(graphql.ObjectConfig{ + Name: "RootMutation", + Fields: mutations.GetRootFields(), + }), + } + + schema, err := graphql.NewSchema(schemaConfig) + + if err != nil { + log.Fatalf("Failed to create new schema, error: %v", err) + } + + httpHandler := handler.New(&handler.Config{ + Schema: &schema, + }) + + postgres.DBConnect() + defer postgres.DBClose() + + http.Handle("/", httpHandler) + log.Print("ready: listening...\n") + + http.ListenAndServe(":8383", nil) + +} diff --git a/mutations/mutations.go b/mutations/mutations.go new file mode 100644 index 0000000..1636973 --- /dev/null +++ b/mutations/mutations.go @@ -0,0 +1,12 @@ +package mutations + +import ( + "github.com/graphql-go/graphql" +) + +// GetRootFields returns all the available mutations. +func GetRootFields() graphql.Fields { + return graphql.Fields{ + "createUser": GetCreateUserMutation(), + } +} \ No newline at end of file diff --git a/mutations/requests.go b/mutations/requests.go new file mode 100644 index 0000000..5d18cce --- /dev/null +++ b/mutations/requests.go @@ -0,0 +1,5 @@ +package mutations + +const ( + ADD_USER = `INSERT INTO users (firstname, lastname) VALUES ($1, $2)` +) diff --git a/mutations/user.go b/mutations/user.go new file mode 100644 index 0000000..6d307ff --- /dev/null +++ b/mutations/user.go @@ -0,0 +1,35 @@ +package mutations + +import ( + "cadoles/graphql/postgres" + "cadoles/graphql/types" + + "github.com/graphql-go/graphql" +) + +// GetCreateUserMutation creates a new user and returns it. +func GetCreateUserMutation() *graphql.Field { + return &graphql.Field{ + Type: types.UserType, + Args: graphql.FieldConfigArgument{ + "firstname": &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(graphql.String), + }, + "lastname": &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(graphql.String), + }, + }, + Resolve: func(params graphql.ResolveParams) (interface{}, error) { + user := &types.User{ + Firstname: params.Args["firstname"].(string), + Lastname: params.Args["lastname"].(string), + } + + _, err := postgres.DB.Exec(ADD_USER, user.Firstname, user.Lastname) + if err != nil { + panic(err) + } + return user, nil + }, + } +} diff --git a/postgres/postgres.go b/postgres/postgres.go new file mode 100644 index 0000000..8647c60 --- /dev/null +++ b/postgres/postgres.go @@ -0,0 +1,37 @@ +package postgres + +import ( + "database/sql" + "fmt" + + _ "github.com/lib/pq" +) + +const ( + DB_HOST = "localhost" + DB_PORT = "5432" + DB_USER = "graphql" + DB_PASSWORD = "graphql" + DB_NAME = "graphql" +) + +var ( + DB *sql.DB +) + +func checkErr(err error, DB *sql.DB) { + if err != nil { + panic(err) + } +} + +func DBConnect() { + dbinfo := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", + DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME) + var err error + DB, err = sql.Open("postgres", dbinfo) + checkErr(err, DB) +} +func DBClose() { + DB.Close() +} diff --git a/queries/queries.go b/queries/queries.go new file mode 100644 index 0000000..2347b31 --- /dev/null +++ b/queries/queries.go @@ -0,0 +1,12 @@ +package queries + +import ( + "github.com/graphql-go/graphql" +) + +// GetRootFields returns all the available queries. +func GetRootFields() graphql.Fields { + return graphql.Fields{ + "user": GetUserQuery(), + } +} diff --git a/queries/requests.go b/queries/requests.go new file mode 100644 index 0000000..5daf983 --- /dev/null +++ b/queries/requests.go @@ -0,0 +1,5 @@ +package queries + +const ( + GET_USERS = `SELECT * FROM users` +) diff --git a/queries/user.go b/queries/user.go new file mode 100644 index 0000000..ce3fc49 --- /dev/null +++ b/queries/user.go @@ -0,0 +1,37 @@ +package queries + +import ( + "cadoles/graphql/postgres" + "cadoles/graphql/types" + "log" + + "github.com/graphql-go/graphql" +) + +// GetUserQuery returns the queries available against user type. +func GetUserQuery() *graphql.Field { + log.Print("GetUserQuery") + return &graphql.Field{ + Type: graphql.NewList(types.UserType), + Resolve: func(params graphql.ResolveParams) (interface{}, error) { + var user types.User + users := []types.User{} + + sqlStatement := GET_USERS + rows, err := postgres.DB.Query(sqlStatement) + if err != nil { + log.Fatal(err) + } + defer rows.Close() + for rows.Next() { + + err := rows.Scan(&user.ID, &user.Firstname, &user.Lastname) + users = append(users, user) + if err != nil { + log.Fatalln(err) + } + } + return users, nil + }, + } +} diff --git a/types/role.go b/types/role.go new file mode 100644 index 0000000..b5ad076 --- /dev/null +++ b/types/role.go @@ -0,0 +1,20 @@ +package types + +import ( + "github.com/graphql-go/graphql" +) + +// Role type definition. +type Role struct { + ID int `db:"id" json:"id"` + Name string `db:"name" json:"name"` +} + +// RoleType is the GraphQL schema for the user type. +var RoleType = graphql.NewObject(graphql.ObjectConfig{ + Name: "Role", + Fields: graphql.Fields{ + "id": &graphql.Field{Type: graphql.Int}, + "name": &graphql.Field{Type: graphql.String}, + }, +}) diff --git a/types/user.go b/types/user.go new file mode 100644 index 0000000..41dbd61 --- /dev/null +++ b/types/user.go @@ -0,0 +1,33 @@ +package types + +import ( + "github.com/graphql-go/graphql" +) + +// User type definition. +type User struct { + ID int `db:"id" json:"id"` + Firstname string `db:"firstname" json:"firstname"` + Lastname string `db:"lastname" json:"lastname"` +} + +// UserType is the GraphQL schema for the user type. +var UserType = graphql.NewObject(graphql.ObjectConfig{ + Name: "User", + Fields: graphql.Fields{ + "id": &graphql.Field{Type: graphql.Int}, + "firstname": &graphql.Field{Type: graphql.String}, + "lastname": &graphql.Field{Type: graphql.String}, + "roles": &graphql.Field{ + Type: graphql.NewList(RoleType), + Resolve: func(params graphql.ResolveParams) (interface{}, error) { + var roles []Role + + // userID := params.Source.(User).ID + // Implement logic to retrieve user associated roles from user id here. + + return roles, nil + }, + }, + }, +})