Skip to content
This repository has been archived by the owner on Aug 16, 2022. It is now read-only.

Commit

Permalink
refactor: graphql resolvers (#105)
Browse files Browse the repository at this point in the history
* refactor gql

* refactor context

* rename
  • Loading branch information
rot1024 committed Feb 2, 2022
1 parent 805d788 commit 01a4e67
Show file tree
Hide file tree
Showing 31 changed files with 372 additions and 1,110 deletions.
84 changes: 84 additions & 0 deletions internal/adapter/context.go
@@ -0,0 +1,84 @@
package adapter

import (
"context"

"github.com/reearth/reearth-backend/internal/usecase"
"github.com/reearth/reearth-backend/internal/usecase/interfaces"
"github.com/reearth/reearth-backend/pkg/user"
)

type ContextKey string

const (
contextUser ContextKey = "user"
contextOperator ContextKey = "operator"
contextSub ContextKey = "sub"
contextUsecases ContextKey = "usecases"
)

func AttachUser(ctx context.Context, u *user.User) context.Context {
return context.WithValue(ctx, contextUser, u)
}

func AttachOperator(ctx context.Context, o *usecase.Operator) context.Context {
return context.WithValue(ctx, contextOperator, o)
}

func AttachSub(ctx context.Context, sub string) context.Context {
return context.WithValue(ctx, contextSub, sub)
}

func AttachUsecases(ctx context.Context, u *interfaces.Container) context.Context {
ctx = context.WithValue(ctx, contextUsecases, u)
return ctx
}

func User(ctx context.Context) *user.User {
if v := ctx.Value(contextUser); v != nil {
if u, ok := v.(*user.User); ok {
return u
}
}
return nil
}

func Lang(ctx context.Context, lang *string) string {
if lang != nil && *lang != "" {
return *lang
}

u := User(ctx)
if u == nil {
return "en" // default language
}

l := u.Lang()
if l.IsRoot() {
return "en" // default language
}

return l.String()
}

func Operator(ctx context.Context) *usecase.Operator {
if v := ctx.Value(contextOperator); v != nil {
if v2, ok := v.(*usecase.Operator); ok {
return v2
}
}
return nil
}

func Sub(ctx context.Context) string {
if v := ctx.Value(contextSub); v != nil {
if v2, ok := v.(string); ok {
return v2
}
}
return ""
}

func Usecases(ctx context.Context) *interfaces.Container {
return ctx.Value(contextUsecases).(*interfaces.Container)
}
65 changes: 30 additions & 35 deletions internal/adapter/gql/context.go
Expand Up @@ -3,59 +3,54 @@ package gql
import (
"context"

"github.com/reearth/reearth-backend/internal/adapter"
"github.com/reearth/reearth-backend/internal/usecase"
"github.com/reearth/reearth-backend/internal/usecase/interfaces"
"github.com/reearth/reearth-backend/pkg/user"
)

type ContextKey string

const (
ContextUser ContextKey = "user"
ContextOperator ContextKey = "operator"
ContextSub ContextKey = "sub"
contextLoaders ContextKey = "loaders"
contextDataloaders ContextKey = "dataloaders"
)

func AttachUsecases(ctx context.Context, u *interfaces.Container, enableDataLoaders bool) context.Context {
loaders := NewLoaders(u)
dataloaders := loaders.DataLoadersWith(ctx, enableDataLoaders)

ctx = adapter.AttachUsecases(ctx, u)
ctx = context.WithValue(ctx, contextLoaders, loaders)
ctx = context.WithValue(ctx, contextDataloaders, dataloaders)

return ctx
}

func getUser(ctx context.Context) *user.User {
if v := ctx.Value(ContextUser); v != nil {
if u, ok := v.(*user.User); ok {
return u
}
}
return nil
return adapter.User(ctx)
}

func getLang(ctx context.Context, lang *string) string {
if lang != nil && *lang != "" {
return *lang
}
return adapter.Lang(ctx, lang)
}

u := getUser(ctx)
if u == nil {
return "en" // default language
}
func getOperator(ctx context.Context) *usecase.Operator {
return adapter.Operator(ctx)
}

l := u.Lang()
if l.IsRoot() {
return "en" // default language
}
func getSub(ctx context.Context) string {
return adapter.Sub(ctx)
}

return l.String()
func usecases(ctx context.Context) *interfaces.Container {
return adapter.Usecases(ctx)
}

func getOperator(ctx context.Context) *usecase.Operator {
if v := ctx.Value(ContextOperator); v != nil {
if v2, ok := v.(*usecase.Operator); ok {
return v2
}
}
return nil
func loaders(ctx context.Context) *Loaders {
return ctx.Value(contextLoaders).(*Loaders)
}

func getSub(ctx context.Context) string {
if v := ctx.Value(ContextSub); v != nil {
if v2, ok := v.(string); ok {
return v2
}
}
return ""
func dataloaders(ctx context.Context) *DataLoaders {
return ctx.Value(contextDataloaders).(*DataLoaders)
}
29 changes: 11 additions & 18 deletions internal/adapter/gql/loader.go
Expand Up @@ -45,9 +45,12 @@ type DataLoaders struct {
TagGroup TagGroupDataLoader
}

func NewLoaders(usecases interfaces.Container) Loaders {
return Loaders{
usecases: usecases,
func NewLoaders(usecases *interfaces.Container) *Loaders {
if usecases == nil {
return nil
}
return &Loaders{
usecases: *usecases,
Asset: NewAssetLoader(usecases.Asset),
Dataset: NewDatasetLoader(usecases.Dataset),
Layer: NewLayerLoader(usecases.Layer),
Expand All @@ -61,15 +64,15 @@ func NewLoaders(usecases interfaces.Container) Loaders {
}
}

func (l Loaders) DataLoadersWith(ctx context.Context, enabled bool) DataLoaders {
func (l Loaders) DataLoadersWith(ctx context.Context, enabled bool) *DataLoaders {
if enabled {
return l.DataLoaders(ctx)
}
return l.OrdinaryDataLoaders(ctx)
}

func (l Loaders) DataLoaders(ctx context.Context) DataLoaders {
return DataLoaders{
func (l Loaders) DataLoaders(ctx context.Context) *DataLoaders {
return &DataLoaders{
Asset: l.Asset.DataLoader(ctx),
Dataset: l.Dataset.DataLoader(ctx),
DatasetSchema: l.Dataset.SchemaDataLoader(ctx),
Expand All @@ -89,8 +92,8 @@ func (l Loaders) DataLoaders(ctx context.Context) DataLoaders {
}
}

func (l Loaders) OrdinaryDataLoaders(ctx context.Context) DataLoaders {
return DataLoaders{
func (l Loaders) OrdinaryDataLoaders(ctx context.Context) *DataLoaders {
return &DataLoaders{
Asset: l.Asset.OrdinaryDataLoader(ctx),
Dataset: l.Dataset.OrdinaryDataLoader(ctx),
DatasetSchema: l.Dataset.SchemaOrdinaryDataLoader(ctx),
Expand All @@ -109,13 +112,3 @@ func (l Loaders) OrdinaryDataLoaders(ctx context.Context) DataLoaders {
TagGroup: l.Tag.GroupDataLoader(ctx),
}
}

type dataLoadersKey struct{}

func DataLoadersFromContext(ctx context.Context) DataLoaders {
return ctx.Value(dataLoadersKey{}).(DataLoaders)
}

func DataLoadersKey() interface{} {
return dataLoadersKey{}
}
12 changes: 3 additions & 9 deletions internal/adapter/gql/resolver.go
Expand Up @@ -4,8 +4,6 @@ package gql

import (
"errors"

"github.com/reearth/reearth-backend/internal/usecase/interfaces"
)

// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.
Expand All @@ -14,15 +12,11 @@ var ErrNotImplemented = errors.New("not impleneted yet")
var ErrUnauthorized = errors.New("unauthorized")

type Resolver struct {
usecases interfaces.Container
loaders Loaders
debug bool
debug bool
}

func NewResolver(loaders Loaders, debug bool) ResolverRoot {
func NewResolver(debug bool) ResolverRoot {
return &Resolver{
usecases: loaders.usecases,
loaders: loaders,
debug: debug,
debug: debug,
}
}
5 changes: 1 addition & 4 deletions internal/adapter/gql/resolver_asset.go
Expand Up @@ -14,8 +14,5 @@ func (r *Resolver) Asset() AssetResolver {
type assetResolver struct{ *Resolver }

func (r *assetResolver) Team(ctx context.Context, obj *gqlmodel.Asset) (*gqlmodel.Team, error) {
exit := trace(ctx)
defer exit()

return DataLoadersFromContext(ctx).Team.Load(id.TeamID(obj.TeamID))
return dataloaders(ctx).Team.Load(id.TeamID(obj.TeamID))
}
25 changes: 5 additions & 20 deletions internal/adapter/gql/resolver_dataset.go
Expand Up @@ -18,17 +18,11 @@ func (r *Resolver) DatasetField() DatasetFieldResolver {
type datasetResolver struct{ *Resolver }

func (r *datasetResolver) Schema(ctx context.Context, obj *gqlmodel.Dataset) (*gqlmodel.DatasetSchema, error) {
exit := trace(ctx)
defer exit()

return DataLoadersFromContext(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
return dataloaders(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
}

func (r *datasetResolver) Name(ctx context.Context, obj *gqlmodel.Dataset) (*string, error) {
exit := trace(ctx)
defer exit()

ds, err := DataLoadersFromContext(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
ds, err := dataloaders(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
if err != nil || ds == nil || ds.RepresentativeFieldID == nil {
return nil, err
}
Expand All @@ -46,30 +40,21 @@ func (r *datasetResolver) Name(ctx context.Context, obj *gqlmodel.Dataset) (*str
type datasetFieldResolver struct{ *Resolver }

func (r *datasetFieldResolver) Field(ctx context.Context, obj *gqlmodel.DatasetField) (*gqlmodel.DatasetSchemaField, error) {
exit := trace(ctx)
defer exit()

ds, err := DataLoadersFromContext(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
ds, err := dataloaders(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
return ds.Field(obj.FieldID), err
}

func (r *datasetFieldResolver) Schema(ctx context.Context, obj *gqlmodel.DatasetField) (*gqlmodel.DatasetSchema, error) {
exit := trace(ctx)
defer exit()

return DataLoadersFromContext(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
return dataloaders(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
}

func (r *datasetFieldResolver) ValueRef(ctx context.Context, obj *gqlmodel.DatasetField) (*gqlmodel.Dataset, error) {
exit := trace(ctx)
defer exit()

if obj.Value == nil {
return nil, nil
}
idstr, ok := (obj.Value).(id.ID)
if !ok {
return nil, nil
}
return DataLoadersFromContext(ctx).Dataset.Load(id.DatasetID(idstr))
return dataloaders(ctx).Dataset.Load(id.DatasetID(idstr))
}
23 changes: 4 additions & 19 deletions internal/adapter/gql/resolver_dataset_schema.go
Expand Up @@ -19,16 +19,10 @@ func (r *Resolver) DatasetSchemaField() DatasetSchemaFieldResolver {
type datasetSchemaResolver struct{ *Resolver }

func (r *datasetSchemaResolver) Scene(ctx context.Context, obj *gqlmodel.DatasetSchema) (*gqlmodel.Scene, error) {
exit := trace(ctx)
defer exit()

return DataLoadersFromContext(ctx).Scene.Load(id.SceneID(obj.SceneID))
return dataloaders(ctx).Scene.Load(id.SceneID(obj.SceneID))
}

func (r *datasetSchemaResolver) RepresentativeField(ctx context.Context, obj *gqlmodel.DatasetSchema) (*gqlmodel.DatasetSchemaField, error) {
exit := trace(ctx)
defer exit()

if obj.RepresentativeFieldID == nil {
return nil, nil
}
Expand All @@ -42,27 +36,18 @@ func (r *datasetSchemaResolver) RepresentativeField(ctx context.Context, obj *gq
}

func (r *datasetSchemaResolver) Datasets(ctx context.Context, obj *gqlmodel.DatasetSchema, first *int, last *int, after *usecase.Cursor, before *usecase.Cursor) (*gqlmodel.DatasetConnection, error) {
exit := trace(ctx)
defer exit()

return r.loaders.Dataset.FindBySchema(ctx, obj.ID, first, last, before, after)
return loaders(ctx).Dataset.FindBySchema(ctx, obj.ID, first, last, before, after)
}

type datasetSchemaFieldResolver struct{ *Resolver }

func (r *datasetSchemaFieldResolver) Schema(ctx context.Context, obj *gqlmodel.DatasetSchemaField) (*gqlmodel.DatasetSchema, error) {
exit := trace(ctx)
defer exit()

return DataLoadersFromContext(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
return dataloaders(ctx).DatasetSchema.Load(id.DatasetSchemaID(obj.SchemaID))
}

func (r *datasetSchemaFieldResolver) Ref(ctx context.Context, obj *gqlmodel.DatasetSchemaField) (*gqlmodel.DatasetSchema, error) {
exit := trace(ctx)
defer exit()

if obj.RefID == nil {
return nil, nil
}
return DataLoadersFromContext(ctx).DatasetSchema.Load(id.DatasetSchemaID(*obj.RefID))
return dataloaders(ctx).DatasetSchema.Load(id.DatasetSchemaID(*obj.RefID))
}

0 comments on commit 01a4e67

Please sign in to comment.