Skip to content
This repository was archived by the owner on Mar 22, 2021. It is now read-only.

Commit ae65625

Browse files
committed
Added board, member, comment models and some mutations
1 parent f68b35b commit ae65625

File tree

10 files changed

+430
-47
lines changed

10 files changed

+430
-47
lines changed

docs/Spec.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,10 @@ type AccessToken {
7777

7878
```graphql
7979
type Board {
80-
id: Int!
81-
name: String! # URL이 되는 이름
82-
readableName: String! # UI상으로 노출되는 이름
83-
readPermission: BoardPermission!
84-
writePermission: BoardPermission!
85-
commentPermission: BoardPermission!
80+
name: String! # UI상으로 노출되는 이름
81+
urlPath: String! # URL 상으로 표현되는 경로
82+
readPermission: BoardPermission!
83+
writePermission: BoardPermission!
8684
}
8785

8886
enum BoardPermission {

go.mod

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,28 @@ module nagase
22

33
require (
44
bou.ke/monkey v1.0.1 // indirect
5+
cloud.google.com/go v0.30.0 // indirect
56
github.com/bouk/monkey v1.0.1
67
github.com/davecgh/go-spew v1.1.1 // indirect
8+
github.com/denisenkom/go-mssqldb v0.0.0-20180901172138-1eb28afdf9b6 // indirect
79
github.com/dgrijalva/jwt-go v3.2.0+incompatible
10+
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect
11+
github.com/go-sql-driver/mysql v1.4.0 // indirect
12+
github.com/google/go-cmp v0.2.0 // indirect
13+
github.com/gorilla/handlers v1.4.0
814
github.com/graphql-go/graphql v0.7.6
9-
github.com/graphql-go/handler v0.2.1
15+
github.com/graphql-go/handler v0.2.2-0.20180922162246-83cde2468fa5
1016
github.com/jinzhu/gorm v1.9.1
1117
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect
18+
github.com/jinzhu/now v0.0.0-20180511015916-ed742868f2ae // indirect
19+
github.com/kr/pretty v0.1.0 // indirect
1220
github.com/lib/pq v1.0.0 // indirect
21+
github.com/mattn/go-sqlite3 v1.9.0 // indirect
1322
github.com/pmezard/go-difflib v1.0.0 // indirect
1423
github.com/satori/go.uuid v1.2.0
1524
github.com/stretchr/testify v1.2.2 // indirect
1625
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b
1726
golang.org/x/sys v0.0.0-20180921163948-d47a0f339242 // indirect
27+
google.golang.org/appengine v1.2.0 // indirect
28+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
1829
)

go.sum

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,45 @@
11
bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U=
22
bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg=
3+
cloud.google.com/go v0.30.0 h1:xKvyLgk56d0nksWq49J0UyGEeUIicTl4+UBiX1NPX9g=
4+
cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
35
github.com/bouk/monkey v1.0.1 h1:82kWEtyEjyfkRZb0DaQ5+7O5dJfe3GzF/o97+yUo5d0=
46
github.com/bouk/monkey v1.0.1/go.mod h1:PG/63f4XEUlVyW1ttIeOJmJhhe1+t9EC/je3eTjvFhE=
57
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
68
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/denisenkom/go-mssqldb v0.0.0-20180901172138-1eb28afdf9b6 h1:BZGp1dbKFjqlGmxEpwkDpCWNxVwEYnUPoncIzLiHlPo=
10+
github.com/denisenkom/go-mssqldb v0.0.0-20180901172138-1eb28afdf9b6/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
711
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
812
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
13+
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
14+
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
15+
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
16+
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
17+
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
18+
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
19+
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
20+
github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZsA=
21+
github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
922
github.com/graphql-go/graphql v0.7.6 h1:3Bn1IFB5OvPoANEfu03azF8aMyks0G/H6G1XeTfYbM4=
1023
github.com/graphql-go/graphql v0.7.6/go.mod h1:k6yrAYQaSP59DC5UVxbgxESlmVyojThKdORUqGDGmrI=
1124
github.com/graphql-go/handler v0.2.1 h1:WbIbeiYSkLEB0yLqjfsPGZWquZIXCD79RYvEsfnRJ1c=
1225
github.com/graphql-go/handler v0.2.1/go.mod h1:leLF6RpV5uZMN1CdImAxuiayrYYhOk33bZciaUGaXeU=
26+
github.com/graphql-go/handler v0.2.2-0.20180922162246-83cde2468fa5 h1:br+PXgQU2ohUCZSb179Hk6MmBa3IVUmwWvh/0ULTe1s=
27+
github.com/graphql-go/handler v0.2.2-0.20180922162246-83cde2468fa5/go.mod h1:leLF6RpV5uZMN1CdImAxuiayrYYhOk33bZciaUGaXeU=
1328
github.com/jinzhu/gorm v1.9.1 h1:lDSDtsCt5AGGSKTs8AHlSDbbgif4G4+CKJ8ETBDVHTA=
1429
github.com/jinzhu/gorm v1.9.1/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
1530
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k=
1631
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
32+
github.com/jinzhu/now v0.0.0-20180511015916-ed742868f2ae h1:8bBMcboXYVuo0WYH+rPe5mB8obO89a993hdTZ3phTjc=
33+
github.com/jinzhu/now v0.0.0-20180511015916-ed742868f2ae/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc=
34+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
35+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
36+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
37+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
38+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
1739
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
1840
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
41+
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
42+
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
1943
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2044
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2145
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
@@ -24,5 +48,11 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
2448
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
2549
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b h1:2b9XGzhjiYsYPnKXoEfL7klWZQIt8IfyRCz62gCqqlQ=
2650
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
51+
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
2752
golang.org/x/sys v0.0.0-20180921163948-d47a0f339242 h1:5DYsa+ZAwcJHjuY0Qet390sUr7qwkpnRsUNjddyc0b8=
2853
golang.org/x/sys v0.0.0-20180921163948-d47a0f339242/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
54+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
55+
google.golang.org/appengine v1.2.0 h1:S0iUepdCWODXRvtE+gcRDd15L+k+k1AiHlMiMjefH24=
56+
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
57+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
58+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

main.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package main
33
import (
44
"context"
55
"net/http"
6+
"os"
67
"strings"
78

9+
"github.com/gorilla/handlers"
810
"github.com/graphql-go/graphql"
911
"github.com/graphql-go/handler"
1012

@@ -15,24 +17,32 @@ import (
1517
func main() {
1618
schema, _ := graphql.NewSchema(graphql.SchemaConfig{
1719
Query: graphql.NewObject(graphql.ObjectConfig{
18-
Name: "RootQuery",
20+
Name: "RootQuery",
1921
Fields: graphql.Fields{
20-
"me": models.MeQuery,
22+
"me": models.MeQuery,
23+
"boards": models.BoardsQuery,
24+
"post": models.PostQuery,
2125
},
2226
}),
2327
Mutation: graphql.NewObject(graphql.ObjectConfig{
2428
Name: "RootMutation",
2529
Fields: graphql.Fields{
2630
"createAccessToken": models.CreateAccessTokenMutation,
27-
"createMember": models.CreateMemberMutation,
31+
"createMember": models.CreateMemberMutation,
32+
"createPost": models.CreatePostMutation,
33+
"createComment": models.CreateCommentMutation,
2834
},
2935
}),
3036
})
3137

3238
// Set GraphQL endpoint.
33-
h := handler.New(&handler.Config{Schema: &schema})
39+
h := handler.New(&handler.Config{
40+
Schema: &schema,
41+
Playground: true,
42+
})
3443

35-
http.Handle("/graphql", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
44+
server := http.NewServeMux()
45+
server.Handle("/graphql", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3646
// CORS configurations.
3747
w.Header().Set("Access-Control-Allow-Origin", "*")
3848
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
@@ -45,20 +55,20 @@ func main() {
4555
memberUUID, _, err := auth.ValidatedToken(strings.Split(authorization, " ")[1])
4656
if err != nil {
4757
w.WriteHeader(http.StatusUnauthorized)
48-
return
58+
return
4959
}
5060

5161
member, err := models.GetMemberByUUID(memberUUID)
5262
if err != nil {
5363
w.WriteHeader(http.StatusUnauthorized)
54-
return
64+
return
5565
}
5666

5767
ctx = context.WithValue(ctx, "member", member)
5868
}
5969

6070
h.ContextHandler(ctx, w, r)
61-
}))
71+
})))
6272

63-
http.ListenAndServe(":8080", nil)
73+
http.ListenAndServe(":8080", handlers.CompressHandler(server))
6474
}

models/access_token.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@ var CreateAccessTokenMutation = &graphql.Field{
2424
Type: accessTokenType,
2525
Description: "Access Token을 발급합니다.",
2626
Args: graphql.FieldConfigArgument{
27-
"user_id": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)},
27+
"loginID": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)},
2828
"password": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)},
2929
},
3030
Resolve: func(params graphql.ResolveParams) (interface{}, error) {
31-
userID, _ := params.Args["user_id"].(string)
31+
loginID, _ := params.Args["loginID"].(string)
3232
password, _ := params.Args["password"].(string)
3333

34-
// Get the member by user id and password.
34+
// Get the member by login id and password.
3535
member := new(Member)
36-
database.DB.Where(&Member{UserID: userID}).First(&member)
36+
database.DB.Where(&Member{LoginID: loginID}).First(&member)
3737
if member.UUID == "" || !member.ValidatePassword(password) || !member.IsActivated {
38-
return nil, fmt.Errorf("invalid user id or password")
38+
return nil, fmt.Errorf("invalid login id or password")
3939
}
4040

4141
// If token not exists or expired, generate new token.

models/board.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package models
2+
3+
import (
4+
"time"
5+
6+
"github.com/graphql-go/graphql"
7+
8+
"nagase/components/database"
9+
)
10+
11+
type Board struct {
12+
ID int
13+
Name string `gorm:"type:varchar(40);UNIQUE_INDEX"`
14+
URLPath string `gorm:"type:varchar(40);UNIQUE_INDEX"`
15+
ReadPermission string `gorm:"type:varchar(10)"`
16+
WritePermission string `gorm:"type:varchar(10)"`
17+
18+
CreatedAt time.Time
19+
UpdatedAt time.Time
20+
}
21+
22+
type BoardType struct {
23+
Name string
24+
URLPath string
25+
ReadPermission string
26+
WritePermission string
27+
}
28+
29+
func (board Board) toGraphQLType() BoardType {
30+
return BoardType{
31+
Name: board.Name,
32+
URLPath: board.URLPath,
33+
ReadPermission: board.ReadPermission,
34+
WritePermission: board.WritePermission,
35+
}
36+
}
37+
38+
var boardType = graphql.NewObject(graphql.ObjectConfig{
39+
Name: "Board",
40+
Fields: graphql.Fields{
41+
"name": &graphql.Field{Type: graphql.NewNonNull(graphql.String)},
42+
"urlPath": &graphql.Field{Type: graphql.NewNonNull(graphql.String)},
43+
"readPermission": &graphql.Field{Type: graphql.NewNonNull(graphql.String)},
44+
"writePermission": &graphql.Field{Type: graphql.NewNonNull(graphql.String)},
45+
},
46+
})
47+
48+
// Queries
49+
var BoardsQuery = &graphql.Field{
50+
Type: graphql.NewList(boardType),
51+
Description: "게시판 목록을 조회합니다",
52+
Resolve: func(params graphql.ResolveParams) (interface{}, error) {
53+
var boards []Board
54+
database.DB.Find(&boards)
55+
56+
var boardTypes []BoardType
57+
for _, b := range boards {
58+
boardTypes = append(boardTypes, b.toGraphQLType())
59+
}
60+
61+
return boardTypes, nil
62+
},
63+
}

models/comment.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package models
2+
3+
import (
4+
"fmt"
5+
"nagase/components/database"
6+
"time"
7+
8+
"github.com/graphql-go/graphql"
9+
)
10+
11+
type Comment struct {
12+
ID int
13+
14+
PostID int `gorm:"INDEX"`
15+
AuthorUUID string
16+
Body string `gorm:"type:varchar(40)"`
17+
18+
CreatedAt time.Time
19+
UpdatedAt time.Time
20+
}
21+
22+
type CommentType struct {
23+
ID int
24+
Author MemberType
25+
Body string
26+
CreatedAt time.Time
27+
}
28+
29+
func (comment Comment) toGraphQLType() CommentType {
30+
author, _ := GetMemberByUUID(comment.AuthorUUID)
31+
return CommentType{
32+
ID: comment.ID,
33+
Author: author.toGraphQLType(),
34+
Body: comment.Body,
35+
CreatedAt: comment.CreatedAt,
36+
}
37+
}
38+
39+
var commentType = graphql.NewObject(graphql.ObjectConfig{
40+
Name: "Comment",
41+
Fields: graphql.Fields{
42+
"id": &graphql.Field{Type: graphql.NewNonNull(graphql.Int)},
43+
"author": &graphql.Field{Type: graphql.NewNonNull(memberType)},
44+
"body": &graphql.Field{Type: graphql.NewNonNull(graphql.String)},
45+
"created_at": &graphql.Field{Type: graphql.NewNonNull(graphql.DateTime)},
46+
},
47+
})
48+
49+
// Mutations
50+
var CreateCommentMutation = &graphql.Field{
51+
Type: postType,
52+
Description: "댓글을 작성합니다.",
53+
Args: graphql.FieldConfigArgument{
54+
"postID": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.Int)},
55+
"body": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)},
56+
},
57+
Resolve: func(params graphql.ResolveParams) (interface{}, error) {
58+
if params.Context.Value("member") == nil {
59+
return nil, fmt.Errorf("unauthorized")
60+
}
61+
member := params.Context.Value("member").(*Member)
62+
63+
// Get board and check permission.
64+
// All users who has read permission can create comments.
65+
postID, _ := params.Args["postID"].(int)
66+
post := new(Post)
67+
database.DB.Where(&Post{ID: postID}).First(&post)
68+
if post.ID == 0 {
69+
return nil, fmt.Errorf("bad request")
70+
}
71+
72+
board := new(Board)
73+
database.DB.Where(&Board{ID: post.BoardID}).First(&board)
74+
if board.ID == 0 {
75+
return nil, fmt.Errorf("bad request")
76+
} else if board.ReadPermission == "ADMIN" && !member.IsAdmin {
77+
return nil, fmt.Errorf("forbidden")
78+
}
79+
80+
// Create new comment
81+
body, _ := params.Args["body"].(string)
82+
comment := Comment{
83+
PostID: postID,
84+
AuthorUUID: member.UUID,
85+
Body: body,
86+
}
87+
88+
errs := database.DB.Save(&comment).GetErrors()
89+
if len(errs) > 0 {
90+
return nil, errs[0]
91+
}
92+
return comment.toGraphQLType(), nil
93+
},
94+
}

models/init.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import "nagase/components/database"
44

55
func init() {
66
database.DB.AutoMigrate(
7+
&Board{},
78
&Member{},
9+
&Post{},
10+
&Comment{},
811
)
912
}

0 commit comments

Comments
 (0)