Skip to content

Instantly share code, notes, and snippets.

@nomkhonwaan
Last active April 18, 2020 10:59
Show Gist options
  • Save nomkhonwaan/c2665fa0c0b3f399fb54b0811e71d67d to your computer and use it in GitHub Desktop.
Save nomkhonwaan/c2665fa0c0b3f399fb54b0811e71d67d to your computer and use it in GitHub Desktop.
เว็บบล็อกเวอร์ชัน-2-1-code-refactoring-5e6b952d6f62018fc5b8ff23
/* schema.go */
// BuildSchema accepts build schema function(s) for applying to the schemabuilding.Schema object
func BuildSchema(buildSchemaFunc ...func(*schemabuilder.Schema)) (*graphql.Schema, error) {
s := schemabuilder.NewSchema()
for _, f := range buildSchemaFunc {
f(s)
}
return s.Build()
}
// BuildPostSchema builds all post related schemas
func BuildPostSchema(repository blog.PostRepository) func(*schemabuilder.Schema) {
return func(s *schemabuilder.Schema) {
...
m := s.Mutation()
m.FieldFunc("updatePostTitle", UpdatePostTitleFieldFunc(repository))
...
}
}
// UpdatePostTitleFieldFunc handles the following mutation
// ```graphql
// mutation {
// updatePostTitle(slug: string!, title: string!) { ... }
// }
// ```
func UpdatePostTitleFieldFunc(repository blog.PostRepository) interface{} {
return func(ctx context.Context, args struct {
Slug Slug
Title string
}) (blog.Post, error) {
id := args.Slug.MustGetID()
p, err := repository.FindByID(ctx, id)
if err != nil {
return blog.Post{}, errors.New(http.StatusText(http.StatusNotFound))
}
if authID := ctx.Value(AuthorizedID); authID != nil {
if p.AuthorID == authID.(string) {
slug := fmt.Sprintf("%s-%s", slugify.Make(args.Title), id.(primitive.ObjectID).Hex())
return repository.Save(ctx, id, blog.NewPostQueryBuilder().WithTitle(args.Title).WithSlug(slug).
Build())
}
}
return blog.Post{}, errors.New(http.StatusText(http.StatusForbidden))
}
}
/* server.go */
// NewServer returns new GraphQL server
func NewServer(blogService blog.Service, fbClient facebook.Client, file storage.FileRepository) *Server {
return &Server{
service: service{
Service: blogService,
fbClient: fbClient,
file: file,
},
schema: schemabuilder.NewSchema(),
}
}
/* mutation.go */
// RegisterMutation registers pre-defined mutation fields to the provided schema
func (s *Server) RegisterMutation(schema *schemabuilder.Schema) {
obj := schema.Mutation()
obj.FieldFunc("updatePostTitle", s.updatePostTitleMutation)
...
}
// mutation {
// updatePostTitle(slug: string!, title: string!) {
// ...
// }
// }
func (s *Server) updatePostTitleMutation(ctx context.Context, args struct {
Slug Slug
Title string
}) (blog.Post, error) {
id := args.Slug.MustGetID()
err := s.validateAuthority(ctx, id)
if err != nil {
return blog.Post{}, err
}
slug := fmt.Sprintf("%s-%s", slugify.Make(args.Title), id.(primitive.ObjectID).Hex())
return s.service.Post().Save(ctx, id, blog.NewPostQueryBuilder().WithTitle(args.Title).WithSlug(slug).Build())
}
/* storage.go */
// Storage uses to storing or retrieving file from cloud or remote server
type Storage interface {
Delete(ctx context.Context, path string) error
Download(ctx context.Context, path string) (io.ReadCloser, error)
Upload(ctx context.Context, body io.Reader, path string) error
}
/* blob.go */
// Bucket embeds the original blob.Bucket for providing compatible storage.Storage interface methods
type Bucket struct{ *blob.Bucket }
// Download provides compatible Download method of the storage.Storage interface
func (b *Bucket) Download(ctx context.Context, path string) (io.ReadCloser, error) {
return b.Bucket.NewReader(ctx, path, nil)
}
// Upload provides compatible Upload method of the storage.Storage interface
func (b *Bucket) Upload(ctx context.Context, body io.Reader, path string) error {
w, err := b.Bucket.NewWriter(ctx, path, nil)
if err != nil {
return err
}
_, err = io.Copy(w, body)
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment