Implemented aero GraphQL server

This commit is contained in:
Eduard Urbach 2019-05-11 16:03:37 +09:00
parent 751d10448e
commit a48e053de4
4 changed files with 103 additions and 5 deletions

2
go.mod
View File

@ -10,7 +10,7 @@ require (
github.com/aerogo/api v0.1.6
github.com/aerogo/codetree v1.2.2 // indirect
github.com/aerogo/crawler v0.2.1
github.com/aerogo/graphql v0.1.4
github.com/aerogo/graphql v0.3.3
github.com/aerogo/http v1.0.3
github.com/aerogo/layout v0.1.5
github.com/aerogo/log v0.2.4

8
go.sum
View File

@ -43,8 +43,10 @@ github.com/aerogo/csp v0.1.5 h1:4l8AaMWndSb0t/03onf4lc0th2zoaapmtKgysDIznW4=
github.com/aerogo/csp v0.1.5/go.mod h1:KNqnTFffuDwIPJxBEFTl3baBx+x3Vw+9kcMfu5APFJA=
github.com/aerogo/flow v0.1.2 h1:fZ3V7Bo7jwBjqnM1mWxYbg5O/FlQX2XovzMZU2D+o5M=
github.com/aerogo/flow v0.1.2/go.mod h1:xXIb7GY0AKouhbp4/ViCsiOmvvgRGonqPG30d6FnACI=
github.com/aerogo/graphql v0.1.4 h1:NMMr0N5lTtaC8gfLhlKN46gVLCkrDHDZWPdjdmPRIYQ=
github.com/aerogo/graphql v0.1.4/go.mod h1:qAPqMXgv4ZUpDTIZzJT/AHDoWq7h6IMnDeaOCw52zyM=
github.com/aerogo/graphql v0.3.2 h1:M9tQw3nEp7NThL/IcYlrpwajLzkxuZi5OX0Oq/ox1hA=
github.com/aerogo/graphql v0.3.2/go.mod h1:bcAaQk3IGODFLF2gFwVszP3hyumWOhwKKuOh1xClSeI=
github.com/aerogo/graphql v0.3.3 h1:PyqTuEUErrLQWo80hKjVzO2YPbQBrYrRkJKARrUaRC0=
github.com/aerogo/graphql v0.3.3/go.mod h1:bcAaQk3IGODFLF2gFwVszP3hyumWOhwKKuOh1xClSeI=
github.com/aerogo/http v1.0.0 h1:15a7Px8wGZbmgFqJMR1kBy3fWFkDfMZWexJzxhmFKe4=
github.com/aerogo/http v1.0.0/go.mod h1:B1igUmMLpE6KabMpc9reHCJJNUOJ2U/PR9s1fF3TpPQ=
github.com/aerogo/http v1.0.1 h1:KTzYarhp5yougurxuAhJKFh3YvZ7R7CfaDVwJv5+xIs=
@ -67,6 +69,8 @@ github.com/aerogo/mirror v0.1.3 h1:813FatCdChOvgWen2EcZNnRfxAeo9zmu/TgDNOnsDx0=
github.com/aerogo/mirror v0.1.3/go.mod h1:Un87Jq8RIRrb2bU1CxVToJjVZgSMLUQXxVLCXln4rUU=
github.com/aerogo/mirror v0.2.0 h1:iaQtEejSU3PytPOHrHSEWBYmAoM0Pc63YGFQUMTXWjY=
github.com/aerogo/mirror v0.2.0/go.mod h1:Un87Jq8RIRrb2bU1CxVToJjVZgSMLUQXxVLCXln4rUU=
github.com/aerogo/mirror v0.2.2 h1:kASC9ZsTDBPwzZehb2o5qLbNv+bj8t9V167ExjEMRS0=
github.com/aerogo/mirror v0.2.2/go.mod h1:Un87Jq8RIRrb2bU1CxVToJjVZgSMLUQXxVLCXln4rUU=
github.com/aerogo/nano v0.1.6 h1:FtWokAa8SZcm5kHlW10OkaUnqlFE4eQGvEfkiSBVsek=
github.com/aerogo/nano v0.1.6/go.mod h1:NxWlxJWtm2s4gB4CcJGy5Lsofz1ZgvEGtv5dEQVNa94=
github.com/aerogo/nano v0.2.0 h1:qcCdCsAtN1Qpw8DhZQXiLVJYsjmpQMmZ7TPFD2GkwVw=

94
graphql/graphql.go Normal file
View File

@ -0,0 +1,94 @@
package graphql
import (
"errors"
"fmt"
"reflect"
"strings"
"github.com/aerogo/aero"
"github.com/aerogo/graphql"
"github.com/animenotifier/arn"
)
var (
empty = struct{}{}
privateCollections = map[string]struct{}{
"PayPalPayment": empty,
"Purchase": empty,
"EmailToUser": empty,
"Session": empty,
"EditLogEntry": empty,
}
)
func Install(app *aero.Application) {
api := graphql.New(arn.DB)
// Block private collections
api.AddRootResolver(func(name string, arguments graphql.Map) (interface{}, error, bool) {
typeName := strings.TrimPrefix(name, "all")
typeName = strings.TrimPrefix(typeName, "like")
_, private := privateCollections[typeName]
if private {
return nil, fmt.Errorf("Type '%s' is private", typeName), true
}
return nil, nil, false
})
// Like objects
api.AddRootResolver(func(name string, arguments graphql.Map) (interface{}, error, bool) {
if !strings.HasPrefix(name, "like") {
return nil, nil, false
}
id, ok := arguments["ID"].(string)
if !ok {
return nil, fmt.Errorf("'%s' needs to specify an ID", name), true
}
typeName := strings.TrimPrefix(name, "like")
obj, err := arn.DB.Get(typeName, id)
if err != nil {
return nil, err, true
}
field := reflect.ValueOf(obj).Elem().FieldByName("IsDraft")
if field.IsValid() && field.Bool() {
return nil, errors.New("Drafts need to be published before they can be liked"), true
}
likeable, ok := obj.(arn.Likeable)
if !ok {
return nil, fmt.Errorf("'%s' does not implement the Likeable interface", name), true
}
// TODO: Authentication
// user := GetUserFromContext(ctx)
// if user == nil {
// return errors.New("Not logged in")
// }
// likeable.Like(user.ID)
// Call OnLike if the object implements it
// receiver, ok := likeable.(LikeEventReceiver)
// if ok {
// receiver.OnLike(user)
// }
likeable.Save()
return obj, nil, true
})
app.Post("/graphql", api.Handler())
}

View File

@ -4,10 +4,10 @@ import (
"strings"
"github.com/aerogo/aero"
"github.com/aerogo/graphql"
nanostore "github.com/aerogo/session-store-nano"
"github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/auth"
"github.com/animenotifier/notify.moe/graphql"
"github.com/animenotifier/notify.moe/middleware"
"github.com/animenotifier/notify.moe/pages"
"github.com/animenotifier/notify.moe/utils/routetests"
@ -61,7 +61,7 @@ func configure(app *aero.Application) *aero.Application {
auth.Install(app)
// GraphQL
app.Post("/graphql", graphql.Handler(arn.DB))
graphql.Install(app)
// Close the database node on shutdown
app.OnEnd(arn.Node.Close)