Add blog service & follow model changes in tags/posts (#22)

This commit is contained in:
Janos Dobronszki
2020-11-03 14:14:00 +01:00
committed by GitHub
parent 3642f7279d
commit b30adabfc3
20 changed files with 415 additions and 117 deletions

3
blog/Dockerfile Normal file
View File

@@ -0,0 +1,3 @@
FROM alpine
ADD blog /blog
ENTRYPOINT [ "/blog" ]

22
blog/Makefile Normal file
View File

@@ -0,0 +1,22 @@
GOPATH:=$(shell go env GOPATH)
.PHONY: init
init:
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
go get github.com/micro/micro/v3/cmd/protoc-gen-micro
.PHONY: proto
proto:
protoc --proto_path=$$GOPATH/src:. --micro_out=. --go_out=:. proto/blog.proto
.PHONY: build
build:
go build -o blog *.go
.PHONY: test
test:
go test -v ./... -cover
.PHONY: docker
docker:
docker build . -t blog:latest

View File

@@ -11,7 +11,7 @@ import (
)
type Comments struct {
comments model.Table
comments model.Model
idIndex model.Index
postIndex model.Index
}
@@ -25,7 +25,7 @@ func NewComments() *Comments {
idIndex.Order.Type = model.OrderTypeUnordered
return &Comments{
comments: model.NewTable(store.DefaultStore, "users", model.Indexes(postIndex), nil),
comments: model.New(store.DefaultStore, "users", model.Indexes(postIndex), nil),
postIndex: postIndex,
idIndex: idIndex,
}

2
blog/generate.go Normal file
View File

@@ -0,0 +1,2 @@
package main
//go:generate make proto

30
blog/handler/blog.go Normal file
View File

@@ -0,0 +1,30 @@
package handler
import (
"context"
comments "github.com/micro/services/blog/comments/proto"
posts "github.com/micro/services/blog/posts/proto"
proto "github.com/micro/services/blog/proto"
tags "github.com/micro/services/blog/tags/proto"
)
type Blog struct {
ps posts.PostsService
cs comments.CommentsService
ts tags.TagsService
}
func NewBlog(ps posts.PostsService,
cs comments.CommentsService,
ts tags.TagsService) *Blog {
return &Blog{
ps: ps,
cs: cs,
ts: ts,
}
}
func (e *Blog) Latest(ctx context.Context, req *proto.LatestRequest, rsp *proto.LatestResponse) error {
return nil
}

31
blog/main.go Normal file
View File

@@ -0,0 +1,31 @@
package main
import (
comments "github.com/micro/services/blog/comments/proto"
"github.com/micro/services/blog/handler"
posts "github.com/micro/services/blog/posts/proto"
proto "github.com/micro/services/blog/proto"
tags "github.com/micro/services/blog/tags/proto"
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"
)
func main() {
// Create service
srv := service.New(
service.Name("blog"),
)
// Register handler
proto.RegisterBlogHandler(srv.Server(), handler.NewBlog(
posts.NewPostsService("posts", srv.Client()),
comments.NewCommentsService("comments", srv.Client()),
tags.NewTagsService("tags", srv.Client()),
))
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}

1
blog/micro.mu Normal file
View File

@@ -0,0 +1 @@
service blog

View File

@@ -5,7 +5,7 @@ MODIFY=Mgithub.com/micro/micro/proto/api/api.proto=github.com/micro/micro/v3/pro
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=${MODIFY}:. --go_out=${MODIFY}:. proto/posts/posts.proto
protoc --proto_path=. --micro_out=${MODIFY}:. --go_out=${MODIFY}:. proto/posts.proto
.PHONY: build

View File

@@ -11,8 +11,7 @@ import (
"github.com/micro/dev/model"
"github.com/gosimple/slug"
pb "github.com/micro/services/blog/posts/proto/posts"
posts "github.com/micro/services/blog/posts/proto/posts"
proto "github.com/micro/services/blog/posts/proto"
tags "github.com/micro/services/blog/tags/proto"
)
@@ -20,19 +19,9 @@ const (
tagType = "post-tag"
)
type Post struct {
ID string `json:"id"`
Title string `json:"title"`
Slug string `json:"slug"`
Content string `json:"content"`
Created int64 `json:"created"`
Updated int64 `json:"updated"`
Tags []string `json:"tags"`
}
type Posts struct {
Tags tags.TagsService
db model.Table
db model.Model
}
func NewPosts(tagsService tags.TagsService) *Posts {
@@ -41,35 +30,35 @@ func NewPosts(tagsService tags.TagsService) *Posts {
return &Posts{
Tags: tagsService,
db: model.NewTable(
db: model.New(
store.DefaultStore,
"posts",
model.Indexes(model.ByEquality("slug"), createdIndex),
&model.TableOptions{
&model.ModelOptions{
Debug: false,
},
),
}
}
func (p *Posts) Save(ctx context.Context, req *posts.SaveRequest, rsp *posts.SaveResponse) error {
func (p *Posts) Save(ctx context.Context, req *proto.SaveRequest, rsp *proto.SaveResponse) error {
if len(req.Id) == 0 {
return errors.BadRequest("posts.save.input-check", "Id is missing")
return errors.BadRequest("proto.save.input-check", "Id is missing")
}
// read by post
posts := []Post{}
posts := []*proto.Post{}
q := model.Equals("id", req.Id)
q.Order.Type = model.OrderTypeUnordered
err := p.db.List(q, &posts)
if err != nil {
return errors.InternalServerError("posts.save.store-id-read", "Failed to read post by id: %v", err.Error())
return errors.InternalServerError("proto.save.store-id-read", "Failed to read post by id: %v", err.Error())
}
postSlug := slug.Make(req.Title)
// If no existing record is found, create a new one
if len(posts) == 0 {
post := &Post{
ID: req.Id,
post := &proto.Post{
Id: req.Id,
Title: req.Title,
Content: req.Content,
Tags: req.Tags,
@@ -78,14 +67,14 @@ func (p *Posts) Save(ctx context.Context, req *posts.SaveRequest, rsp *posts.Sav
}
err := p.savePost(ctx, nil, post)
if err != nil {
return errors.InternalServerError("posts.save.post-save", "Failed to save new post: %v", err.Error())
return errors.InternalServerError("proto.save.post-save", "Failed to save new post: %v", err.Error())
}
return nil
}
oldPost := &posts[0]
oldPost := posts[0]
post := &Post{
ID: req.Id,
post := &proto.Post{
Id: req.Id,
Title: oldPost.Title,
Content: oldPost.Content,
Slug: oldPost.Slug,
@@ -112,22 +101,22 @@ func (p *Posts) Save(ctx context.Context, req *posts.SaveRequest, rsp *posts.Sav
}
}
postsWithThisSlug := []Post{}
postsWithThisSlug := []*proto.Post{}
err = p.db.List(model.Equals("slug", postSlug), &postsWithThisSlug)
if err != nil {
return errors.InternalServerError("posts.save.store-read", "Failed to read post by slug: %v", err.Error())
return errors.InternalServerError("proto.save.store-read", "Failed to read post by slug: %v", err.Error())
}
if len(postsWithThisSlug) > 0 {
if oldPost.ID != postsWithThisSlug[0].ID {
return errors.BadRequest("posts.save.slug-check", "An other post with this slug already exists")
if oldPost.Id != postsWithThisSlug[0].Id {
return errors.BadRequest("proto.save.slug-check", "An other post with this slug already exists")
}
}
return p.savePost(ctx, oldPost, post)
}
func (p *Posts) savePost(ctx context.Context, oldPost, post *Post) error {
func (p *Posts) savePost(ctx context.Context, oldPost, post *proto.Post) error {
err := p.db.Save(post)
if err != nil {
return err
@@ -135,7 +124,7 @@ func (p *Posts) savePost(ctx context.Context, oldPost, post *Post) error {
if oldPost == nil {
for _, tagName := range post.Tags {
_, err := p.Tags.Add(ctx, &tags.AddRequest{
ResourceID: post.ID,
ResourceID: post.Id,
Type: tagType,
Title: tagName,
})
@@ -145,7 +134,7 @@ func (p *Posts) savePost(ctx context.Context, oldPost, post *Post) error {
}
return nil
}
return p.diffTags(ctx, post.ID, oldPost.Tags, post.Tags)
return p.diffTags(ctx, post.Id, oldPost.Tags, post.Tags)
}
func (p *Posts) diffTags(ctx context.Context, parentID string, oldTagNames, newTagNames []string) error {
@@ -186,7 +175,7 @@ func (p *Posts) diffTags(ctx context.Context, parentID string, oldTagNames, newT
return nil
}
func (p *Posts) Query(ctx context.Context, req *pb.QueryRequest, rsp *pb.QueryResponse) error {
func (p *Posts) Query(ctx context.Context, req *proto.QueryRequest, rsp *proto.QueryResponse) error {
var q model.Query
if len(req.Slug) > 0 {
logger.Infof("Reading post by slug: %v", req.Slug)
@@ -208,15 +197,15 @@ func (p *Posts) Query(ctx context.Context, req *pb.QueryRequest, rsp *pb.QueryRe
logger.Infof("Listing posts, offset: %v, limit: %v", req.Offset, limit)
}
posts := []Post{}
posts := []*proto.Post{}
err := p.db.List(q, &posts)
if err != nil {
return errors.BadRequest("posts.query.store-read", "Failed to read from store: %v", err.Error())
return errors.BadRequest("proto.query.store-read", "Failed to read from store: %v", err.Error())
}
rsp.Posts = make([]*pb.Post, len(posts))
rsp.Posts = make([]*proto.Post, len(posts))
for i, post := range posts {
rsp.Posts[i] = &pb.Post{
Id: post.ID,
rsp.Posts[i] = &proto.Post{
Id: post.Id,
Title: post.Title,
Slug: post.Slug,
Content: post.Content,
@@ -226,7 +215,7 @@ func (p *Posts) Query(ctx context.Context, req *pb.QueryRequest, rsp *pb.QueryRe
return nil
}
func (p *Posts) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.DeleteResponse) error {
func (p *Posts) Delete(ctx context.Context, req *proto.DeleteRequest, rsp *proto.DeleteResponse) error {
logger.Info("Received Post.Delete request")
return p.db.Delete(model.Equals("id", req.Id))
}

View File

@@ -1,5 +1,5 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/micro/services/blog/posts/proto/posts/posts.proto
// source: proto/posts.proto
package posts
@@ -38,7 +38,7 @@ func (m *Post) Reset() { *m = Post{} }
func (m *Post) String() string { return proto.CompactTextString(m) }
func (*Post) ProtoMessage() {}
func (*Post) Descriptor() ([]byte, []int) {
return fileDescriptor_ead3372a32dfec97, []int{0}
return fileDescriptor_e93dc7d934d9dc10, []int{0}
}
func (m *Post) XXX_Unmarshal(b []byte) error {
@@ -132,7 +132,7 @@ func (m *QueryRequest) Reset() { *m = QueryRequest{} }
func (m *QueryRequest) String() string { return proto.CompactTextString(m) }
func (*QueryRequest) ProtoMessage() {}
func (*QueryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ead3372a32dfec97, []int{1}
return fileDescriptor_e93dc7d934d9dc10, []int{1}
}
func (m *QueryRequest) XXX_Unmarshal(b []byte) error {
@@ -199,7 +199,7 @@ func (m *QueryResponse) Reset() { *m = QueryResponse{} }
func (m *QueryResponse) String() string { return proto.CompactTextString(m) }
func (*QueryResponse) ProtoMessage() {}
func (*QueryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_ead3372a32dfec97, []int{2}
return fileDescriptor_e93dc7d934d9dc10, []int{2}
}
func (m *QueryResponse) XXX_Unmarshal(b []byte) error {
@@ -245,7 +245,7 @@ func (m *SaveRequest) Reset() { *m = SaveRequest{} }
func (m *SaveRequest) String() string { return proto.CompactTextString(m) }
func (*SaveRequest) ProtoMessage() {}
func (*SaveRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ead3372a32dfec97, []int{3}
return fileDescriptor_e93dc7d934d9dc10, []int{3}
}
func (m *SaveRequest) XXX_Unmarshal(b []byte) error {
@@ -319,7 +319,7 @@ func (m *SaveResponse) Reset() { *m = SaveResponse{} }
func (m *SaveResponse) String() string { return proto.CompactTextString(m) }
func (*SaveResponse) ProtoMessage() {}
func (*SaveResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_ead3372a32dfec97, []int{4}
return fileDescriptor_e93dc7d934d9dc10, []int{4}
}
func (m *SaveResponse) XXX_Unmarshal(b []byte) error {
@@ -358,7 +358,7 @@ func (m *DeleteRequest) Reset() { *m = DeleteRequest{} }
func (m *DeleteRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteRequest) ProtoMessage() {}
func (*DeleteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_ead3372a32dfec97, []int{5}
return fileDescriptor_e93dc7d934d9dc10, []int{5}
}
func (m *DeleteRequest) XXX_Unmarshal(b []byte) error {
@@ -396,7 +396,7 @@ func (m *DeleteResponse) Reset() { *m = DeleteResponse{} }
func (m *DeleteResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteResponse) ProtoMessage() {}
func (*DeleteResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_ead3372a32dfec97, []int{6}
return fileDescriptor_e93dc7d934d9dc10, []int{6}
}
func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
@@ -428,34 +428,32 @@ func init() {
}
func init() {
proto.RegisterFile("github.com/micro/services/blog/posts/proto/posts/posts.proto", fileDescriptor_ead3372a32dfec97)
proto.RegisterFile("proto/posts.proto", fileDescriptor_e93dc7d934d9dc10)
}
var fileDescriptor_ead3372a32dfec97 = []byte{
// 397 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x4b, 0xee, 0xd3, 0x30,
0x10, 0xc6, 0xc9, 0xf3, 0x4f, 0xa7, 0x0f, 0x55, 0x6e, 0x41, 0x56, 0x85, 0x20, 0x64, 0xd5, 0x55,
0x23, 0x0a, 0x12, 0x1b, 0x96, 0x1c, 0x00, 0xc2, 0x09, 0xd2, 0xc4, 0x4d, 0x2d, 0x25, 0x75, 0x88,
0x27, 0x95, 0x38, 0x07, 0xa7, 0xe0, 0x0a, 0x9c, 0x0e, 0xf9, 0x55, 0xd2, 0x8a, 0xee, 0xd8, 0x44,
0xf3, 0x7d, 0x13, 0x7b, 0x7e, 0xf3, 0x45, 0x81, 0x4f, 0x35, 0xc7, 0xd3, 0x70, 0xd8, 0x95, 0xa2,
0xcd, 0x5a, 0x5e, 0xf6, 0x22, 0x93, 0xac, 0xbf, 0xf0, 0x92, 0xc9, 0xec, 0xd0, 0x88, 0x3a, 0xeb,
0x84, 0x44, 0x99, 0x75, 0xbd, 0x40, 0xe1, 0x6a, 0xf5, 0xdc, 0x69, 0x87, 0x44, 0x5a, 0xa4, 0xbf,
0x3d, 0x08, 0xbf, 0x08, 0x89, 0x64, 0x01, 0x3e, 0xaf, 0xa8, 0x97, 0x78, 0xdb, 0x49, 0xee, 0xf3,
0x8a, 0xac, 0x21, 0x42, 0x8e, 0x0d, 0xa3, 0xbe, 0xb6, 0x8c, 0x20, 0x04, 0x42, 0xd9, 0x0c, 0x35,
0x0d, 0xb4, 0xa9, 0x6b, 0x42, 0xe1, 0xa9, 0x14, 0x67, 0x64, 0x67, 0xa4, 0xa1, 0xb6, 0x9d, 0xd4,
0x9d, 0x9e, 0x15, 0xc8, 0x2a, 0x1a, 0x25, 0xde, 0x36, 0xc8, 0x9d, 0x54, 0x9d, 0xa1, 0xab, 0x74,
0x27, 0x36, 0x1d, 0x2b, 0xc9, 0x4b, 0x88, 0x8b, 0x01, 0x4f, 0xa2, 0xa7, 0x4f, 0xfa, 0x32, 0xab,
0xd4, 0x64, 0x2c, 0x6a, 0x49, 0x9f, 0x27, 0x81, 0x9a, 0xac, 0xea, 0xb4, 0x87, 0xd9, 0xd7, 0x81,
0xf5, 0x3f, 0x72, 0xf6, 0x7d, 0x60, 0xff, 0xd8, 0xc1, 0xd1, 0xfa, 0x23, 0xda, 0x25, 0x04, 0x58,
0xb8, 0x05, 0x54, 0xa9, 0x26, 0x8a, 0xe3, 0x51, 0x32, 0x83, 0x1f, 0xe4, 0x56, 0xa9, 0x04, 0x1a,
0xde, 0x72, 0xb4, 0xec, 0x46, 0xa4, 0x7b, 0x98, 0xdb, 0x99, 0xb2, 0x13, 0x67, 0xc9, 0xc8, 0x5b,
0x30, 0x51, 0x52, 0x2f, 0x09, 0xb6, 0xd3, 0xfd, 0x74, 0x67, 0x52, 0x56, 0xa1, 0xe6, 0x36, 0xe4,
0x9f, 0x1e, 0x4c, 0xbf, 0x15, 0x17, 0xf6, 0x88, 0xf3, 0x7f, 0x64, 0xfd, 0x0a, 0x26, 0xc8, 0x5b,
0x26, 0xb1, 0x68, 0x3b, 0x4b, 0xfc, 0xd7, 0xb8, 0xa6, 0x17, 0x8f, 0xd2, 0x7b, 0x0d, 0x33, 0x03,
0x65, 0x17, 0xb9, 0xa3, 0x4a, 0xdf, 0xc0, 0xfc, 0x33, 0x6b, 0x18, 0x3e, 0xc2, 0x4e, 0x97, 0xb0,
0x70, 0x2f, 0x98, 0x2b, 0xf6, 0xbf, 0x3c, 0x88, 0xd4, 0xe2, 0x92, 0x7c, 0x80, 0x48, 0xc7, 0x44,
0x56, 0x36, 0x8f, 0xf1, 0x87, 0xda, 0xac, 0x6f, 0x4d, 0x73, 0x3a, 0x7d, 0x46, 0xde, 0x41, 0xa8,
0x90, 0x08, 0xb1, 0xfd, 0x51, 0x68, 0x9b, 0xd5, 0x8d, 0x77, 0x3d, 0xf2, 0x11, 0x62, 0x03, 0x41,
0xdc, 0xa5, 0x37, 0xd0, 0x9b, 0x17, 0x77, 0xae, 0x3b, 0x78, 0x88, 0xf5, 0x7f, 0xf0, 0xfe, 0x4f,
0x00, 0x00, 0x00, 0xff, 0xff, 0xce, 0x40, 0x57, 0x3c, 0x47, 0x03, 0x00, 0x00,
var fileDescriptor_e93dc7d934d9dc10 = []byte{
// 367 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x53, 0x5d, 0x4e, 0xf2, 0x50,
0x10, 0xfd, 0x4a, 0x7f, 0xf8, 0x18, 0x7e, 0x82, 0x03, 0x9a, 0x1b, 0x62, 0x14, 0xfb, 0xc4, 0x13,
0x46, 0x34, 0x71, 0x03, 0x2e, 0x40, 0xeb, 0x0a, 0xaa, 0x5c, 0xb0, 0x49, 0xe1, 0xd6, 0xde, 0xa9,
0x89, 0xeb, 0x70, 0x15, 0x6e, 0xc1, 0xd5, 0xd9, 0xfb, 0x53, 0x6c, 0x89, 0xbc, 0xf9, 0x36, 0xe7,
0x9c, 0xce, 0xcc, 0x99, 0xd3, 0x5c, 0x38, 0xca, 0x72, 0x41, 0xe2, 0x32, 0x13, 0x92, 0xe4, 0x5c,
0xd7, 0xe8, 0x6b, 0x10, 0x7e, 0x39, 0xe0, 0xdd, 0x97, 0x15, 0x0e, 0xa0, 0x95, 0x2c, 0x99, 0x33,
0x75, 0x66, 0x9d, 0xa8, 0xac, 0x70, 0x0c, 0x3e, 0x25, 0x94, 0x72, 0xd6, 0xd2, 0x94, 0x01, 0x88,
0xe0, 0xc9, 0xb4, 0x58, 0x33, 0x57, 0x93, 0xba, 0x46, 0x06, 0xed, 0x67, 0xb1, 0x25, 0xbe, 0x25,
0xe6, 0x69, 0xba, 0x82, 0x5a, 0xc9, 0x79, 0x4c, 0x7c, 0xc9, 0xfc, 0x52, 0x71, 0xa3, 0x0a, 0x2a,
0xa5, 0xc8, 0x96, 0x5a, 0x09, 0x8c, 0x62, 0x21, 0x9e, 0x40, 0x10, 0x17, 0xf4, 0x22, 0x72, 0xd6,
0xd6, 0xc3, 0x2c, 0x52, 0x9b, 0x29, 0x5e, 0x4b, 0xf6, 0x7f, 0xea, 0xaa, 0xcd, 0xaa, 0x0e, 0x73,
0xe8, 0x3d, 0x14, 0x3c, 0x7f, 0x8f, 0xf8, 0x6b, 0xc1, 0x7f, 0xb9, 0xa1, 0x72, 0xdb, 0xaa, 0xb9,
0x1d, 0x82, 0x5b, 0xf6, 0xda, 0x03, 0x54, 0xa9, 0x36, 0x8a, 0xd5, 0x4a, 0x72, 0x63, 0xdf, 0x8d,
0x2c, 0x52, 0x09, 0xa4, 0xc9, 0x26, 0x21, 0xeb, 0xdd, 0x80, 0x70, 0x01, 0x7d, 0xbb, 0x53, 0x66,
0x62, 0x2b, 0x39, 0x5e, 0x80, 0x89, 0xb2, 0xdc, 0xeb, 0xce, 0xba, 0x8b, 0xee, 0xdc, 0xa4, 0xac,
0x42, 0x8d, 0x6c, 0xc8, 0x1f, 0x0e, 0x74, 0x1f, 0xe3, 0x37, 0x7e, 0xc8, 0xe7, 0x5f, 0x64, 0x7d,
0x0a, 0x1d, 0x4a, 0x36, 0xe5, 0xf4, 0x78, 0x93, 0x59, 0xc7, 0x3f, 0xc4, 0x2e, 0xbd, 0xa0, 0x96,
0xde, 0x19, 0xf4, 0x8c, 0x29, 0x7b, 0xc8, 0x9e, 0xab, 0xf0, 0x1c, 0xfa, 0x77, 0x3c, 0xe5, 0x74,
0xc8, 0x76, 0x38, 0x84, 0x41, 0xf5, 0x81, 0x19, 0xb1, 0xf8, 0x74, 0xc0, 0x57, 0x87, 0x4b, 0xbc,
0x01, 0x5f, 0xc7, 0x84, 0x23, 0x9b, 0x47, 0xfd, 0x47, 0x4d, 0xc6, 0x4d, 0xd2, 0x74, 0x87, 0xff,
0xf0, 0x0a, 0x3c, 0x65, 0x09, 0xd1, 0xea, 0xb5, 0xd0, 0x26, 0xa3, 0x06, 0xb7, 0x6b, 0xb9, 0x85,
0xc0, 0x98, 0xc0, 0x6a, 0x68, 0xc3, 0xf4, 0xe4, 0x78, 0x8f, 0xad, 0x1a, 0x9f, 0x02, 0xfd, 0x0e,
0xae, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x8c, 0x67, 0xbb, 0x1c, 0x03, 0x00, 0x00,
}

View File

@@ -1,5 +1,5 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: github.com/micro/services/blog/posts/proto/posts/posts.proto
// source: proto/posts.proto
package posts

116
blog/proto/blog.pb.go Normal file
View File

@@ -0,0 +1,116 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: proto/blog.proto
package blog
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
proto1 "github.com/micro/services/blog/posts/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type LatestRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *LatestRequest) Reset() { *m = LatestRequest{} }
func (m *LatestRequest) String() string { return proto.CompactTextString(m) }
func (*LatestRequest) ProtoMessage() {}
func (*LatestRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_fc5203cdc85000bc, []int{0}
}
func (m *LatestRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LatestRequest.Unmarshal(m, b)
}
func (m *LatestRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_LatestRequest.Marshal(b, m, deterministic)
}
func (m *LatestRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_LatestRequest.Merge(m, src)
}
func (m *LatestRequest) XXX_Size() int {
return xxx_messageInfo_LatestRequest.Size(m)
}
func (m *LatestRequest) XXX_DiscardUnknown() {
xxx_messageInfo_LatestRequest.DiscardUnknown(m)
}
var xxx_messageInfo_LatestRequest proto.InternalMessageInfo
type LatestResponse struct {
Latest *proto1.Post `protobuf:"bytes,1,opt,name=latest,proto3" json:"latest,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *LatestResponse) Reset() { *m = LatestResponse{} }
func (m *LatestResponse) String() string { return proto.CompactTextString(m) }
func (*LatestResponse) ProtoMessage() {}
func (*LatestResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_fc5203cdc85000bc, []int{1}
}
func (m *LatestResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LatestResponse.Unmarshal(m, b)
}
func (m *LatestResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_LatestResponse.Marshal(b, m, deterministic)
}
func (m *LatestResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_LatestResponse.Merge(m, src)
}
func (m *LatestResponse) XXX_Size() int {
return xxx_messageInfo_LatestResponse.Size(m)
}
func (m *LatestResponse) XXX_DiscardUnknown() {
xxx_messageInfo_LatestResponse.DiscardUnknown(m)
}
var xxx_messageInfo_LatestResponse proto.InternalMessageInfo
func (m *LatestResponse) GetLatest() *proto1.Post {
if m != nil {
return m.Latest
}
return nil
}
func init() {
proto.RegisterType((*LatestRequest)(nil), "blog.LatestRequest")
proto.RegisterType((*LatestResponse)(nil), "blog.LatestResponse")
}
func init() {
proto.RegisterFile("proto/blog.proto", fileDescriptor_fc5203cdc85000bc)
}
var fileDescriptor_fc5203cdc85000bc = []byte{
// 169 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x28, 0x28, 0xca, 0x2f,
0xc9, 0xd7, 0x4f, 0xca, 0xc9, 0x4f, 0xd7, 0x03, 0x33, 0x85, 0x58, 0x40, 0x6c, 0x29, 0xb3, 0xf4,
0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0xdc, 0xcc, 0xe4, 0xa2, 0x7c, 0xfd,
0xe2, 0xd4, 0xa2, 0xb2, 0xcc, 0xe4, 0xd4, 0x62, 0xb0, 0x5a, 0xfd, 0x82, 0xfc, 0xe2, 0x92, 0x62,
0x7d, 0x88, 0x66, 0x30, 0x1b, 0xa2, 0x5b, 0x89, 0x9f, 0x8b, 0xd7, 0x27, 0xb1, 0x24, 0xb5, 0xb8,
0x24, 0x28, 0xb5, 0xb0, 0x14, 0x48, 0x29, 0x99, 0x72, 0xf1, 0xc1, 0x04, 0x8a, 0x0b, 0xf2, 0xf3,
0x8a, 0x53, 0x85, 0x94, 0xb9, 0xd8, 0x72, 0xc0, 0x22, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46,
0xdc, 0x7a, 0x10, 0x03, 0x02, 0x80, 0x64, 0x10, 0x54, 0xca, 0xc8, 0x96, 0x8b, 0xc5, 0x09, 0x68,
0x8f, 0x90, 0x29, 0x17, 0x1b, 0x44, 0xbb, 0x90, 0xb0, 0x1e, 0xd8, 0x91, 0x28, 0xa6, 0x4b, 0x89,
0xa0, 0x0a, 0x42, 0x6c, 0x50, 0x62, 0x48, 0x62, 0x03, 0xbb, 0xc6, 0x18, 0x10, 0x00, 0x00, 0xff,
0xff, 0xc0, 0x99, 0x61, 0x2b, 0xdf, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,94 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/blog.proto
package blog
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/micro/services/blog/posts/proto"
math "math"
)
import (
context "context"
api "github.com/micro/micro/v3/service/api"
client "github.com/micro/micro/v3/service/client"
server "github.com/micro/micro/v3/service/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// Reference imports to suppress errors if they are not otherwise used.
var _ api.Endpoint
var _ context.Context
var _ client.Option
var _ server.Option
// Api Endpoints for Blog service
func NewBlogEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Blog service
type BlogService interface {
Latest(ctx context.Context, in *LatestRequest, opts ...client.CallOption) (*LatestResponse, error)
}
type blogService struct {
c client.Client
name string
}
func NewBlogService(name string, c client.Client) BlogService {
return &blogService{
c: c,
name: name,
}
}
func (c *blogService) Latest(ctx context.Context, in *LatestRequest, opts ...client.CallOption) (*LatestResponse, error) {
req := c.c.NewRequest(c.name, "Blog.Latest", in)
out := new(LatestResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Blog service
type BlogHandler interface {
Latest(context.Context, *LatestRequest, *LatestResponse) error
}
func RegisterBlogHandler(s server.Server, hdlr BlogHandler, opts ...server.HandlerOption) error {
type blog interface {
Latest(ctx context.Context, in *LatestRequest, out *LatestResponse) error
}
type Blog struct {
blog
}
h := &blogHandler{hdlr}
return s.Handle(s.NewHandler(&Blog{h}, opts...))
}
type blogHandler struct {
BlogHandler
}
func (h *blogHandler) Latest(ctx context.Context, in *LatestRequest, out *LatestResponse) error {
return h.BlogHandler.Latest(ctx, in, out)
}

15
blog/proto/blog.proto Normal file
View File

@@ -0,0 +1,15 @@
syntax = "proto3";
package blog;
import "github.com/micro/services/blog/posts/proto/posts.proto";
service Blog {
rpc Latest(LatestRequest) returns (LatestResponse) {}
}
message LatestRequest {}
message LatestResponse{
posts.Post latest = 1;
}

View File

@@ -11,7 +11,7 @@ import (
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/micro/v3/service/store"
pb "github.com/micro/services/blog/tags/proto"
proto "github.com/micro/services/blog/tags/proto"
)
const (
@@ -20,26 +20,19 @@ const (
childrenByTag = "childrenByTag"
)
type Tag struct {
Title string `json:"title"`
Slug string `json:"slug"`
Type string `json:"type"`
Count int64 `json:"count"`
}
type Tags struct {
db model.Table
db model.Model
}
func NewTags() *Tags {
slugIndex := model.ByEquality("slug")
slugIndex.Order.Type = model.OrderTypeUnordered
return &Tags{
db: model.NewTable(
db: model.New(
store.DefaultStore,
"tags",
model.Indexes(model.ByEquality("type")),
&model.TableOptions{
&model.ModelOptions{
IdIndex: slugIndex,
Debug: false,
},
@@ -47,12 +40,12 @@ func NewTags() *Tags {
}
}
func (t *Tags) Add(ctx context.Context, req *pb.AddRequest, rsp *pb.AddResponse) error {
func (t *Tags) Add(ctx context.Context, req *proto.AddRequest, rsp *proto.AddResponse) error {
if len(req.ResourceID) == 0 || len(req.Type) == 0 {
return errors.BadRequest("tags.increasecount.input-check", "resource id and type is required")
}
tags := []Tag{}
tags := []*proto.Tag{}
tagSlug := slug.Make(req.GetTitle())
q := model.Equals("slug", tagSlug)
q.Order.Type = model.OrderTypeUnordered
@@ -61,16 +54,16 @@ func (t *Tags) Add(ctx context.Context, req *pb.AddRequest, rsp *pb.AddResponse)
return err
}
var tag *Tag
var tag *proto.Tag
// If no existing record is found, create a new one
if len(tags) == 0 {
tag = &Tag{
tag = &proto.Tag{
Title: req.GetTitle(),
Type: req.Type,
Slug: tagSlug,
}
} else {
tag = &tags[0]
tag = tags[0]
}
// increase tag count
@@ -107,12 +100,12 @@ func (t *Tags) Add(ctx context.Context, req *pb.AddRequest, rsp *pb.AddResponse)
return t.saveTag(tag)
}
func (t *Tags) saveTag(tag *Tag) error {
func (t *Tags) saveTag(tag *proto.Tag) error {
tag.Slug = slug.Make(tag.Title)
return t.db.Save(tag)
}
func (t *Tags) Remove(ctx context.Context, req *pb.RemoveRequest, rsp *pb.RemoveResponse) error {
func (t *Tags) Remove(ctx context.Context, req *proto.RemoveRequest, rsp *proto.RemoveResponse) error {
if len(req.ResourceID) == 0 || len(req.Type) == 0 {
return errors.BadRequest("tags.decreaseecount.input-check", "resource id and type is required")
}
@@ -132,7 +125,7 @@ func (t *Tags) Remove(ctx context.Context, req *pb.RemoveRequest, rsp *pb.Remove
return nil
}
record := records[0]
tag := &Tag{}
tag := &proto.Tag{}
err = json.Unmarshal(record.Value, tag)
if err != nil {
return err
@@ -153,7 +146,7 @@ func (t *Tags) Remove(ctx context.Context, req *pb.RemoveRequest, rsp *pb.Remove
return t.saveTag(tag)
}
func (t *Tags) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error {
func (t *Tags) List(ctx context.Context, req *proto.ListRequest, rsp *proto.ListResponse) error {
logger.Info("Received Tags.List request")
// unfortunately there is a mixing of manual indexes
@@ -170,14 +163,14 @@ func (t *Tags) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListRespon
}
if q.Type != "" {
tags := []Tag{}
tags := []proto.Tag{}
err := t.db.List(q, &tags)
if err != nil {
return err
}
rsp.Tags = make([]*pb.Tag, len(tags))
rsp.Tags = make([]*proto.Tag, len(tags))
for i, tag := range tags {
rsp.Tags[i] = &pb.Tag{
rsp.Tags[i] = &proto.Tag{
Title: tag.Title,
Type: tag.Type,
Slug: tag.Slug,
@@ -191,14 +184,14 @@ func (t *Tags) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListRespon
return err
}
rsp.Tags = make([]*pb.Tag, len(records))
rsp.Tags = make([]*proto.Tag, len(records))
for i, record := range records {
tagRecord := &Tag{}
tagRecord := &proto.Tag{}
err := json.Unmarshal(record.Value, tagRecord)
if err != nil {
return err
}
rsp.Tags[i] = &pb.Tag{
rsp.Tags[i] = &proto.Tag{
Title: tagRecord.Title,
Type: tagRecord.Type,
Slug: tagRecord.Slug,
@@ -209,13 +202,13 @@ func (t *Tags) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListRespon
return nil
}
func (t *Tags) Update(ctx context.Context, req *pb.UpdateRequest, rsp *pb.UpdateResponse) error {
func (t *Tags) Update(ctx context.Context, req *proto.UpdateRequest, rsp *proto.UpdateResponse) error {
if len(req.Title) == 0 || len(req.Type) == 0 {
return errors.BadRequest("tags.update.input-check", "title and type is required")
}
tagSlug := slug.Make(req.GetTitle())
tags := []Tag{}
tags := []proto.Tag{}
q := model.Equals("slug", tagSlug)
q.Order.Type = model.OrderTypeUnordered
err := t.db.List(q, &tags)

2
go.mod
View File

@@ -7,7 +7,7 @@ require (
github.com/golang/protobuf v1.4.3
github.com/google/uuid v1.1.2
github.com/gosimple/slug v1.9.0
github.com/micro/dev v0.0.0-20201030123519-9dee6b61fdc2
github.com/micro/dev v0.0.0-20201103105140-02e00085dfa7
github.com/micro/go-micro/v2 v2.9.1 // indirect
github.com/micro/micro/v3 v3.0.0-beta.7
github.com/miekg/dns v1.1.31 // indirect

4
go.sum
View File

@@ -336,6 +336,10 @@ github.com/micro/dev v0.0.0-20201026103917-a7b0e7877fa5 h1:TKVhBhhLeJyWihKdg7bDd
github.com/micro/dev v0.0.0-20201026103917-a7b0e7877fa5/go.mod h1:j/8E+ezN/ij7a9BXBHMKmLayFfUW1O4h/Owdv67B0X0=
github.com/micro/dev v0.0.0-20201030123519-9dee6b61fdc2 h1:AFnDvzVGaoby5itR/Ma85lajomD2wOgtdbLmXhHeTqY=
github.com/micro/dev v0.0.0-20201030123519-9dee6b61fdc2/go.mod h1:j/8E+ezN/ij7a9BXBHMKmLayFfUW1O4h/Owdv67B0X0=
github.com/micro/dev v0.0.0-20201103100745-db13d93e5254 h1:vOpeFmP5cJRvgtIzy8HYTcmzBk0Pb3oTBltCXMmYIt4=
github.com/micro/dev v0.0.0-20201103100745-db13d93e5254/go.mod h1:j/8E+ezN/ij7a9BXBHMKmLayFfUW1O4h/Owdv67B0X0=
github.com/micro/dev v0.0.0-20201103105140-02e00085dfa7 h1:QLkqgpgCphdqEV40rZEuASMobDZmBfk1YjaxnAVTA2E=
github.com/micro/dev v0.0.0-20201103105140-02e00085dfa7/go.mod h1:j/8E+ezN/ij7a9BXBHMKmLayFfUW1O4h/Owdv67B0X0=
github.com/micro/go-micro v1.18.0 h1:gP70EZVHpJuUIT0YWth192JmlIci+qMOEByHm83XE9E=
github.com/micro/go-micro/v2 v2.9.1 h1:+S9koIrNWARjpP6k2TZ7kt0uC9zUJtNXzIdZTZRms7Q=
github.com/micro/go-micro/v2 v2.9.1/go.mod h1:x55ZM3Puy0FyvvkR3e0ha0xsE9DFwfPSUMWAIbFY0SY=

View File

@@ -14,7 +14,7 @@ import (
"time"
"github.com/micro/micro/v3/test"
p "github.com/micro/services/blog/posts/handler"
p "github.com/micro/services/blog/posts/proto"
)
const (
@@ -156,7 +156,7 @@ func testPosts(t *test.T) {
expected := []p.Post{
{
ID: "1",
Id: "1",
Title: "Hi",
Content: "Hi there",
Tags: []string{"a", "b"},
@@ -172,7 +172,7 @@ func testPosts(t *test.T) {
return
}
if expected[0].ID != actual.Posts[0].ID ||
if expected[0].Id != actual.Posts[0].Id ||
expected[0].Title != actual.Posts[0].Title ||
expected[0].Content != actual.Posts[0].Content ||
len(expected[0].Tags) != len(actual.Posts[0].Tags) {

View File

@@ -16,9 +16,9 @@ type pw struct {
}
type Domain struct {
users model.Table
sessions model.Table
passwords model.Table
users model.Model
sessions model.Model
passwords model.Model
nameIndex model.Index
emailIndex model.Index
@@ -40,9 +40,9 @@ func New() *Domain {
idIndex.Order.Type = model.OrderTypeUnordered
return &Domain{
users: model.NewTable(store.DefaultStore, "users", model.Indexes(nameIndex, emailIndex), nil),
sessions: model.NewTable(store.DefaultStore, "sessions", nil, nil),
passwords: model.NewTable(store.DefaultStore, "passwords", nil, nil),
users: model.New(store.DefaultStore, "users", model.Indexes(nameIndex, emailIndex), nil),
sessions: model.New(store.DefaultStore, "sessions", nil, nil),
passwords: model.New(store.DefaultStore, "passwords", nil, nil),
nameIndex: nameIndex,
emailIndex: emailIndex,
idIndex: idIndex,