Autogenerate services.m3o.com (#37)

* Autogenerate services.m3o.com

* Openapi for all

* Gen

* Fix

* Whaat

* Fix dep

* Fix

* Hmm

* Install make

* Debug

* Debug 1

* Location -> locations

* Fix

* Intall protoc gen micro

* F

* F

* F

* Push

* Rename secret

* Fix npm install

* Fix script

* Fix v2

* Ignore errors

* Ignore v2

* F

* F

* F

* Docs index

* Add hugo theme

* Hugo tania fixes

* Change gen

* Change gen 2

* Install hugo

* Change gen

* Gen fix

* Change hugo install

* Change hugo install

* CNAME

* Change articles wording

* Tiny fix

* Fix gen

* Redoc it all

* Fix gen

* Fixing up protos

* Fix proto

* Fix gen

* Fix

* Trigger build

* Fix copy

* Openapi docs

* Flatten

* Changes

* No date vol2

* Changes

* Add make to chat

* Fixes

* Change

* api spec

* replace RSS

* fix link

* Dont continue on error

* increase the width

* use micro at master

* change box colours

* move some things

* Pushing new readmes to see how they look like

* Add skip file

* Readmes

* Nicer api link

* Remove stutter

* FIx mistake

* set service font weight

* Messages readme fix

* add other font bold

* Notes

* Remove post from url

* Revert "Remove post from url"

This reverts commit 5fea2c23d0bafa910f5dc4d4cc63f71f578530e3.

* move exampleSite to site

* replace exampleSite with site

* update readme

* use filename for post

* update index

* Add source urls

* set source as params

* set source as params

* Fix entries

* Generator in go

* Fixes to generator

* F

* Change doc gen

* FIx cname

* Fixing protos

* Change to makefiles

* Fix gen script

Co-authored-by: Asim Aslam <asim@aslam.me>
This commit is contained in:
Janos Dobronszki
2021-01-19 16:59:25 +00:00
committed by GitHub
parent ec81db0753
commit 40b71a9cf9
174 changed files with 10914 additions and 3157 deletions

View File

@@ -7,8 +7,13 @@ init:
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
protoc --openapi_out=. --proto_path=$$GOPATH/src:. --micro_out=. --go_out=:. proto/blog.proto
.PHONY: docs
docs:
protoc --openapi_out=. --proto_path=$$GOPATH/src:. --micro_out=. --go_out=:. proto/blog.proto
@redoc-cli bundle api-protobuf.json
.PHONY: build
build:
go build -o blog *.go

View File

@@ -1,2 +0,0 @@
comment-service

View File

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

View File

@@ -1,22 +0,0 @@
GOPATH:=$(shell go env GOPATH)
MODIFY=Mgithub.com/micro/micro/proto/api/api.proto=github.com/micro/micro/v3/proto/api
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=${MODIFY}:. --go_out=${MODIFY}:. proto/comments.proto
.PHONY: build
build: proto
go build -o comments-service *.go
.PHONY: test
test:
go test -v ./... -cover
.PHONY: docker
docker:
docker build . -t comments-service:latest

View File

@@ -1,3 +0,0 @@
# Comments Service
Still yet to implement

View File

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

View File

@@ -1,46 +0,0 @@
package handler
import (
"context"
"time"
"github.com/google/uuid"
"github.com/micro/dev/model"
"github.com/micro/micro/v3/service/store"
pb "github.com/micro/services/blog/comments/proto"
)
type Comments struct {
comments model.Model
idIndex model.Index
postIndex model.Index
}
func NewComments() *Comments {
postIndex := model.ByEquality("post")
postIndex.Order.Type = model.OrderTypeDesc
postIndex.Order.FieldName = "created"
idIndex := model.ByEquality("id")
idIndex.Order.Type = model.OrderTypeUnordered
return &Comments{
comments: model.New(store.DefaultStore, "users", model.Indexes(postIndex), nil),
postIndex: postIndex,
idIndex: idIndex,
}
}
func (c *Comments) New(ctx context.Context, req *pb.NewRequest, rsp *pb.NewResponse) error {
return c.comments.Save(pb.Comment{
Id: uuid.New().String(),
Post: req.Post,
Author: req.Author,
Message: req.Message,
Created: time.Now().Unix(),
})
}
func (c *Comments) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error {
return c.comments.List(c.postIndex.ToQuery(req.Post), &rsp.Comments)
}

View File

@@ -1,22 +0,0 @@
package main
import (
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/services/blog/comments/handler"
)
func main() {
// Create the service
srv := service.New(
service.Name("comments"),
)
// Register Handler
srv.Handle(handler.NewComments())
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}

View File

@@ -1 +0,0 @@
service comments

View File

@@ -1,290 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: proto/comments.proto
package comments
import (
fmt "fmt"
proto "github.com/golang/protobuf/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 Comment struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Post string `protobuf:"bytes,2,opt,name=post,proto3" json:"post,omitempty"`
Author string `protobuf:"bytes,3,opt,name=author,proto3" json:"author,omitempty"`
Message string `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`
Created int64 `protobuf:"varint,5,opt,name=created,proto3" json:"created,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Comment) Reset() { *m = Comment{} }
func (m *Comment) String() string { return proto.CompactTextString(m) }
func (*Comment) ProtoMessage() {}
func (*Comment) Descriptor() ([]byte, []int) {
return fileDescriptor_44070930b213c2b7, []int{0}
}
func (m *Comment) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Comment.Unmarshal(m, b)
}
func (m *Comment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Comment.Marshal(b, m, deterministic)
}
func (m *Comment) XXX_Merge(src proto.Message) {
xxx_messageInfo_Comment.Merge(m, src)
}
func (m *Comment) XXX_Size() int {
return xxx_messageInfo_Comment.Size(m)
}
func (m *Comment) XXX_DiscardUnknown() {
xxx_messageInfo_Comment.DiscardUnknown(m)
}
var xxx_messageInfo_Comment proto.InternalMessageInfo
func (m *Comment) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Comment) GetPost() string {
if m != nil {
return m.Post
}
return ""
}
func (m *Comment) GetAuthor() string {
if m != nil {
return m.Author
}
return ""
}
func (m *Comment) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func (m *Comment) GetCreated() int64 {
if m != nil {
return m.Created
}
return 0
}
type NewRequest struct {
// post id
Post string `protobuf:"bytes,1,opt,name=post,proto3" json:"post,omitempty"`
// message to leave
Author string `protobuf:"bytes,2,opt,name=author,proto3" json:"author,omitempty"`
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *NewRequest) Reset() { *m = NewRequest{} }
func (m *NewRequest) String() string { return proto.CompactTextString(m) }
func (*NewRequest) ProtoMessage() {}
func (*NewRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_44070930b213c2b7, []int{1}
}
func (m *NewRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NewRequest.Unmarshal(m, b)
}
func (m *NewRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NewRequest.Marshal(b, m, deterministic)
}
func (m *NewRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_NewRequest.Merge(m, src)
}
func (m *NewRequest) XXX_Size() int {
return xxx_messageInfo_NewRequest.Size(m)
}
func (m *NewRequest) XXX_DiscardUnknown() {
xxx_messageInfo_NewRequest.DiscardUnknown(m)
}
var xxx_messageInfo_NewRequest proto.InternalMessageInfo
func (m *NewRequest) GetPost() string {
if m != nil {
return m.Post
}
return ""
}
func (m *NewRequest) GetAuthor() string {
if m != nil {
return m.Author
}
return ""
}
func (m *NewRequest) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
type NewResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *NewResponse) Reset() { *m = NewResponse{} }
func (m *NewResponse) String() string { return proto.CompactTextString(m) }
func (*NewResponse) ProtoMessage() {}
func (*NewResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_44070930b213c2b7, []int{2}
}
func (m *NewResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NewResponse.Unmarshal(m, b)
}
func (m *NewResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NewResponse.Marshal(b, m, deterministic)
}
func (m *NewResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_NewResponse.Merge(m, src)
}
func (m *NewResponse) XXX_Size() int {
return xxx_messageInfo_NewResponse.Size(m)
}
func (m *NewResponse) XXX_DiscardUnknown() {
xxx_messageInfo_NewResponse.DiscardUnknown(m)
}
var xxx_messageInfo_NewResponse proto.InternalMessageInfo
type ListRequest struct {
Post string `protobuf:"bytes,1,opt,name=post,proto3" json:"post,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListRequest) Reset() { *m = ListRequest{} }
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
func (*ListRequest) ProtoMessage() {}
func (*ListRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_44070930b213c2b7, []int{3}
}
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListRequest.Unmarshal(m, b)
}
func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic)
}
func (m *ListRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListRequest.Merge(m, src)
}
func (m *ListRequest) XXX_Size() int {
return xxx_messageInfo_ListRequest.Size(m)
}
func (m *ListRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ListRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ListRequest proto.InternalMessageInfo
func (m *ListRequest) GetPost() string {
if m != nil {
return m.Post
}
return ""
}
type ListResponse struct {
Comments []*Comment `protobuf:"bytes,1,rep,name=comments,proto3" json:"comments,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListResponse) Reset() { *m = ListResponse{} }
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
func (*ListResponse) ProtoMessage() {}
func (*ListResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_44070930b213c2b7, []int{4}
}
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListResponse.Unmarshal(m, b)
}
func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic)
}
func (m *ListResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListResponse.Merge(m, src)
}
func (m *ListResponse) XXX_Size() int {
return xxx_messageInfo_ListResponse.Size(m)
}
func (m *ListResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ListResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ListResponse proto.InternalMessageInfo
func (m *ListResponse) GetComments() []*Comment {
if m != nil {
return m.Comments
}
return nil
}
func init() {
proto.RegisterType((*Comment)(nil), "comments.Comment")
proto.RegisterType((*NewRequest)(nil), "comments.NewRequest")
proto.RegisterType((*NewResponse)(nil), "comments.NewResponse")
proto.RegisterType((*ListRequest)(nil), "comments.ListRequest")
proto.RegisterType((*ListResponse)(nil), "comments.ListResponse")
}
func init() {
proto.RegisterFile("proto/comments.proto", fileDescriptor_44070930b213c2b7)
}
var fileDescriptor_44070930b213c2b7 = []byte{
// 253 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x51, 0xb1, 0x4e, 0xc3, 0x30,
0x10, 0x25, 0x71, 0x68, 0xcb, 0x05, 0x90, 0x38, 0x95, 0xca, 0xea, 0x04, 0x9e, 0xba, 0x50, 0xa4,
0x82, 0xc4, 0xc4, 0xc4, 0x8a, 0x18, 0xfc, 0x07, 0xa1, 0x3d, 0x41, 0x87, 0xd4, 0x21, 0xe7, 0x0a,
0xf5, 0xef, 0x71, 0x1d, 0x3b, 0x0d, 0x11, 0x74, 0xbb, 0xf7, 0xee, 0xdd, 0xbd, 0xf3, 0x33, 0x8c,
0xab, 0xda, 0x58, 0x73, 0xbf, 0x34, 0x65, 0x49, 0x1b, 0xcb, 0x73, 0x0f, 0x71, 0x14, 0xb1, 0xda,
0xc1, 0xf0, 0xa5, 0xa9, 0xf1, 0x12, 0xd2, 0xf5, 0x4a, 0x26, 0x37, 0xc9, 0xec, 0x4c, 0xbb, 0x0a,
0x11, 0xb2, 0xca, 0xb0, 0x95, 0xa9, 0x67, 0x7c, 0x8d, 0x13, 0x18, 0x14, 0x5b, 0xfb, 0x69, 0x6a,
0x29, 0x3c, 0x1b, 0x10, 0x4a, 0x18, 0x96, 0xc4, 0x5c, 0x7c, 0x90, 0xcc, 0x7c, 0x23, 0xc2, 0x7d,
0x67, 0x59, 0x53, 0x61, 0x69, 0x25, 0x4f, 0x5d, 0x47, 0xe8, 0x08, 0x95, 0x06, 0x78, 0xa3, 0x6f,
0x4d, 0x5f, 0x5b, 0x72, 0x9b, 0xa3, 0x5b, 0xf2, 0xa7, 0x5b, 0xfa, 0x9f, 0x9b, 0xf8, 0xe5, 0xa6,
0x2e, 0x20, 0xf7, 0x3b, 0xb9, 0x32, 0x1b, 0x26, 0x75, 0x0b, 0xf9, 0xeb, 0x9a, 0xed, 0x11, 0x0f,
0xf5, 0x0c, 0xe7, 0x8d, 0xa4, 0x19, 0xc1, 0x3b, 0x68, 0xc3, 0x71, 0x3a, 0x31, 0xcb, 0x17, 0x57,
0xf3, 0x36, 0xbd, 0x10, 0x95, 0x6e, 0x25, 0x8b, 0x1d, 0x8c, 0x02, 0xc9, 0xf8, 0x08, 0xc2, 0x99,
0xe3, 0xf8, 0xa0, 0x3f, 0xbc, 0x6f, 0x7a, 0xdd, 0x63, 0xc3, 0x85, 0x27, 0xf8, 0x04, 0xd9, 0xfe,
0x00, 0xec, 0x08, 0x3a, 0x37, 0x4f, 0x27, 0x7d, 0x3a, 0x0e, 0xbe, 0x0f, 0xfc, 0x5f, 0x3e, 0xfc,
0x04, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x0c, 0xe5, 0xcc, 0xe3, 0x01, 0x00, 0x00,
}

View File

@@ -1,110 +0,0 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/comments.proto
package comments
import (
fmt "fmt"
proto "github.com/golang/protobuf/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 Comments service
func NewCommentsEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Comments service
type CommentsService interface {
New(ctx context.Context, in *NewRequest, opts ...client.CallOption) (*NewResponse, error)
List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error)
}
type commentsService struct {
c client.Client
name string
}
func NewCommentsService(name string, c client.Client) CommentsService {
return &commentsService{
c: c,
name: name,
}
}
func (c *commentsService) New(ctx context.Context, in *NewRequest, opts ...client.CallOption) (*NewResponse, error) {
req := c.c.NewRequest(c.name, "Comments.New", in)
out := new(NewResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *commentsService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) {
req := c.c.NewRequest(c.name, "Comments.List", in)
out := new(ListResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Comments service
type CommentsHandler interface {
New(context.Context, *NewRequest, *NewResponse) error
List(context.Context, *ListRequest, *ListResponse) error
}
func RegisterCommentsHandler(s server.Server, hdlr CommentsHandler, opts ...server.HandlerOption) error {
type comments interface {
New(ctx context.Context, in *NewRequest, out *NewResponse) error
List(ctx context.Context, in *ListRequest, out *ListResponse) error
}
type Comments struct {
comments
}
h := &commentsHandler{hdlr}
return s.Handle(s.NewHandler(&Comments{h}, opts...))
}
type commentsHandler struct {
CommentsHandler
}
func (h *commentsHandler) New(ctx context.Context, in *NewRequest, out *NewResponse) error {
return h.CommentsHandler.New(ctx, in, out)
}
func (h *commentsHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error {
return h.CommentsHandler.List(ctx, in, out)
}

View File

@@ -1,6 +1,7 @@
syntax = "proto3";
package comments;
option go_package = "proto;comments";
service Comments {
rpc New(NewRequest) returns (NewResponse) {}

View File

@@ -1,2 +0,0 @@
feeds

View File

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

View File

@@ -1,22 +0,0 @@
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=. --micro_out=. --go_out=:. proto/feeds.proto
.PHONY: build
build:
go build -o feeds *.go
.PHONY: test
test:
go test -v ./... -cover
.PHONY: docker
docker:
docker build . -t feeds:latest

View File

@@ -1,56 +0,0 @@
# Feeds Service
This is the Feeds service
Generated with
```
micro new feeds
```
## Usage
```
micro feeds new --name="a16z" --url=http://a16z.com/feed/
```
```
$ micro posts query
{
"posts": [
{
"id": "39cdfbd6e7534bcd868be9eebbf43f8f",
"title": "Anthony Albanese: From the NYSE to Crypto",
"slug": "anthony-albanese-from-the-nyse-to-crypto",
"created": "1605104742",
"updated": "1605105364",
"metadata": {
"domain": "a16z.com",
"link": "https://a16z.com/2020/10/28/anthony-albanese-from-the-nyse-to-crypto/"
}
},
{
"id": "5e9285c01311704e204322ba564cd99e",
"title": "Journal Club: From Insect Eyes to Nanomaterials",
"slug": "journal-club-from-insect-eyes-to-nanomaterials",
"created": "1605104741",
"updated": "1605105363",
"metadata": {
"domain": "a16z.com",
"link": "https://a16z.com/2020/10/29/journal-club-insect-eyes-nanomaterials/"
}
},
]
}
```
```
make proto
```
Run the service
```
micro run .
```

View File

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

View File

@@ -1,77 +0,0 @@
package handler
import (
"context"
"crypto/md5"
"fmt"
"net/url"
"github.com/SlyMarbo/rss"
log "github.com/micro/micro/v3/service/logger"
feeds "github.com/micro/services/blog/feeds/proto"
posts "github.com/micro/services/blog/posts/proto"
)
func (e *Feeds) fetchAll() {
fs := []*feeds.Feed{}
err := e.feeds.List(e.feedsNameIndex.ToQuery(nil), &fs)
if err != nil {
log.Errorf("Error listing feeds: %v", err)
return
}
if len(fs) == 0 {
log.Infof("No feeds to fetch")
return
}
for _, feed := range fs {
err = e.fetch(feed.Url)
if err != nil {
log.Errorf("Error saving post: %v", err)
}
}
}
func (e *Feeds) fetch(url string) error {
log.Infof("Fetching address %v", url)
fd, err := rss.Fetch(url)
if err != nil {
return fmt.Errorf("Error fetching address %v: %v", url, err)
}
domain := getDomain(url)
for _, item := range fd.Items {
id := fmt.Sprintf("%x", md5.Sum([]byte(item.ID)))
err = e.entries.Save(feeds.Entry{
Id: id,
Url: item.Link,
Title: item.Title,
Domain: domain,
Content: item.Summary,
Date: item.Date.Unix(),
})
if err != nil {
return fmt.Errorf("Error saving item: %v", err)
}
// @todo make this optional
_, err := e.postsService.Save(context.TODO(), &posts.SaveRequest{
Id: id,
Title: item.Title,
Content: item.Content,
Timestamp: item.Date.Unix(),
Metadata: map[string]string{
"domain": domain,
"link": item.Link,
},
})
if err != nil {
return err
}
}
return nil
}
func getDomain(address string) string {
uri, _ := url.Parse(address)
return uri.Host
}

View File

@@ -1,93 +0,0 @@
package handler
import (
"context"
"time"
"github.com/micro/dev/model"
log "github.com/micro/micro/v3/service/logger"
"github.com/micro/micro/v3/service/store"
feeds "github.com/micro/services/blog/feeds/proto"
posts "github.com/micro/services/blog/posts/proto"
)
type Feeds struct {
feeds model.Model
entries model.Model
postsService posts.PostsService
feedsIdIndex model.Index
feedsNameIndex model.Index
entriesDateIndex model.Index
entriesURLIndex model.Index
}
func NewFeeds(postsService posts.PostsService) *Feeds {
idIndex := model.ByEquality("url")
idIndex.Order.Type = model.OrderTypeUnordered
nameIndex := model.ByEquality("name")
nameIndex.Unique = true
nameIndex.Order.Type = model.OrderTypeUnordered
dateIndex := model.ByEquality("date")
dateIndex.Order.Type = model.OrderTypeDesc
entriesURLIndex := model.ByEquality("url")
entriesURLIndex.Order.Type = model.OrderTypeDesc
entriesURLIndex.Order.FieldName = "date"
f := &Feeds{
feeds: model.New(
store.DefaultStore,
"feeds",
model.Indexes(nameIndex),
&model.ModelOptions{
Debug: false,
IdIndex: idIndex,
},
),
entries: model.New(
store.DefaultStore,
"entries",
model.Indexes(dateIndex, entriesURLIndex),
&model.ModelOptions{
Debug: false,
},
),
postsService: postsService,
feedsIdIndex: idIndex,
feedsNameIndex: nameIndex,
entriesDateIndex: dateIndex,
entriesURLIndex: entriesURLIndex,
}
go f.crawl()
return f
}
func (e *Feeds) crawl() {
e.fetchAll()
tick := time.NewTicker(1 * time.Minute)
for _ = range tick.C {
e.fetchAll()
}
}
func (e *Feeds) New(ctx context.Context, req *feeds.NewRequest, rsp *feeds.NewResponse) error {
log.Info("Received Feeds.New request")
e.feeds.Save(feeds.Feed{
Name: req.Name,
Url: req.Url,
})
return nil
}
func (e *Feeds) Entries(ctx context.Context, req *feeds.EntriesRequest, rsp *feeds.EntriesResponse) error {
log.Info("Received Feeds.New request")
err := e.fetch(req.Url)
if err != nil {
return err
}
return e.entries.List(e.entriesURLIndex.ToQuery(req.Url), &rsp.Entries)
}

View File

@@ -1,27 +0,0 @@
package main
import (
pb "github.com/micro/services/blog/feeds/proto"
posts "github.com/micro/services/blog/posts/proto"
"github.com/micro/services/blog/feeds/handler"
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"
)
func main() {
// Create service
srv := service.New(
service.Name("feeds"),
service.Version("latest"),
)
// Register handler
pb.RegisterFeedsHandler(srv.Server(), handler.NewFeeds(posts.NewPostsService("posts", srv.Client())))
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}

View File

@@ -1 +0,0 @@
service feeds

View File

@@ -1,340 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: proto/feeds.proto
package feeds
import (
fmt "fmt"
proto "github.com/golang/protobuf/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 Feed struct {
// rss feed name
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// rss feed url
Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Feed) Reset() { *m = Feed{} }
func (m *Feed) String() string { return proto.CompactTextString(m) }
func (*Feed) ProtoMessage() {}
func (*Feed) Descriptor() ([]byte, []int) {
return fileDescriptor_dd517c38176c13bf, []int{0}
}
func (m *Feed) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Feed.Unmarshal(m, b)
}
func (m *Feed) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Feed.Marshal(b, m, deterministic)
}
func (m *Feed) XXX_Merge(src proto.Message) {
xxx_messageInfo_Feed.Merge(m, src)
}
func (m *Feed) XXX_Size() int {
return xxx_messageInfo_Feed.Size(m)
}
func (m *Feed) XXX_DiscardUnknown() {
xxx_messageInfo_Feed.DiscardUnknown(m)
}
var xxx_messageInfo_Feed proto.InternalMessageInfo
func (m *Feed) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *Feed) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
type Entry struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"`
Title string `protobuf:"bytes,4,opt,name=title,proto3" json:"title,omitempty"`
Content string `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
Date int64 `protobuf:"varint,6,opt,name=date,proto3" json:"date,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Entry) Reset() { *m = Entry{} }
func (m *Entry) String() string { return proto.CompactTextString(m) }
func (*Entry) ProtoMessage() {}
func (*Entry) Descriptor() ([]byte, []int) {
return fileDescriptor_dd517c38176c13bf, []int{1}
}
func (m *Entry) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Entry.Unmarshal(m, b)
}
func (m *Entry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Entry.Marshal(b, m, deterministic)
}
func (m *Entry) XXX_Merge(src proto.Message) {
xxx_messageInfo_Entry.Merge(m, src)
}
func (m *Entry) XXX_Size() int {
return xxx_messageInfo_Entry.Size(m)
}
func (m *Entry) XXX_DiscardUnknown() {
xxx_messageInfo_Entry.DiscardUnknown(m)
}
var xxx_messageInfo_Entry proto.InternalMessageInfo
func (m *Entry) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Entry) GetDomain() string {
if m != nil {
return m.Domain
}
return ""
}
func (m *Entry) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
func (m *Entry) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func (m *Entry) GetContent() string {
if m != nil {
return m.Content
}
return ""
}
func (m *Entry) GetDate() int64 {
if m != nil {
return m.Date
}
return 0
}
type NewRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *NewRequest) Reset() { *m = NewRequest{} }
func (m *NewRequest) String() string { return proto.CompactTextString(m) }
func (*NewRequest) ProtoMessage() {}
func (*NewRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_dd517c38176c13bf, []int{2}
}
func (m *NewRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NewRequest.Unmarshal(m, b)
}
func (m *NewRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NewRequest.Marshal(b, m, deterministic)
}
func (m *NewRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_NewRequest.Merge(m, src)
}
func (m *NewRequest) XXX_Size() int {
return xxx_messageInfo_NewRequest.Size(m)
}
func (m *NewRequest) XXX_DiscardUnknown() {
xxx_messageInfo_NewRequest.DiscardUnknown(m)
}
var xxx_messageInfo_NewRequest proto.InternalMessageInfo
func (m *NewRequest) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *NewRequest) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
type NewResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *NewResponse) Reset() { *m = NewResponse{} }
func (m *NewResponse) String() string { return proto.CompactTextString(m) }
func (*NewResponse) ProtoMessage() {}
func (*NewResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_dd517c38176c13bf, []int{3}
}
func (m *NewResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NewResponse.Unmarshal(m, b)
}
func (m *NewResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_NewResponse.Marshal(b, m, deterministic)
}
func (m *NewResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_NewResponse.Merge(m, src)
}
func (m *NewResponse) XXX_Size() int {
return xxx_messageInfo_NewResponse.Size(m)
}
func (m *NewResponse) XXX_DiscardUnknown() {
xxx_messageInfo_NewResponse.DiscardUnknown(m)
}
var xxx_messageInfo_NewResponse proto.InternalMessageInfo
type EntriesRequest struct {
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EntriesRequest) Reset() { *m = EntriesRequest{} }
func (m *EntriesRequest) String() string { return proto.CompactTextString(m) }
func (*EntriesRequest) ProtoMessage() {}
func (*EntriesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_dd517c38176c13bf, []int{4}
}
func (m *EntriesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EntriesRequest.Unmarshal(m, b)
}
func (m *EntriesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EntriesRequest.Marshal(b, m, deterministic)
}
func (m *EntriesRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_EntriesRequest.Merge(m, src)
}
func (m *EntriesRequest) XXX_Size() int {
return xxx_messageInfo_EntriesRequest.Size(m)
}
func (m *EntriesRequest) XXX_DiscardUnknown() {
xxx_messageInfo_EntriesRequest.DiscardUnknown(m)
}
var xxx_messageInfo_EntriesRequest proto.InternalMessageInfo
func (m *EntriesRequest) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
type EntriesResponse struct {
Entries []*Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EntriesResponse) Reset() { *m = EntriesResponse{} }
func (m *EntriesResponse) String() string { return proto.CompactTextString(m) }
func (*EntriesResponse) ProtoMessage() {}
func (*EntriesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_dd517c38176c13bf, []int{5}
}
func (m *EntriesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EntriesResponse.Unmarshal(m, b)
}
func (m *EntriesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EntriesResponse.Marshal(b, m, deterministic)
}
func (m *EntriesResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_EntriesResponse.Merge(m, src)
}
func (m *EntriesResponse) XXX_Size() int {
return xxx_messageInfo_EntriesResponse.Size(m)
}
func (m *EntriesResponse) XXX_DiscardUnknown() {
xxx_messageInfo_EntriesResponse.DiscardUnknown(m)
}
var xxx_messageInfo_EntriesResponse proto.InternalMessageInfo
func (m *EntriesResponse) GetEntries() []*Entry {
if m != nil {
return m.Entries
}
return nil
}
func init() {
proto.RegisterType((*Feed)(nil), "feeds.Feed")
proto.RegisterType((*Entry)(nil), "feeds.Entry")
proto.RegisterType((*NewRequest)(nil), "feeds.NewRequest")
proto.RegisterType((*NewResponse)(nil), "feeds.NewResponse")
proto.RegisterType((*EntriesRequest)(nil), "feeds.EntriesRequest")
proto.RegisterType((*EntriesResponse)(nil), "feeds.EntriesResponse")
}
func init() {
proto.RegisterFile("proto/feeds.proto", fileDescriptor_dd517c38176c13bf)
}
var fileDescriptor_dd517c38176c13bf = []byte{
// 282 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x51, 0x3d, 0x4f, 0xc3, 0x30,
0x10, 0x25, 0xcd, 0x97, 0xb8, 0xd0, 0x42, 0x4f, 0x50, 0x59, 0x9d, 0x50, 0x06, 0xd4, 0x01, 0x05,
0x29, 0x4c, 0xc0, 0x86, 0x04, 0x23, 0x43, 0x46, 0xb6, 0x40, 0x0e, 0x29, 0x52, 0x6b, 0x97, 0xd8,
0x15, 0xe2, 0x07, 0xf0, 0xbf, 0x71, 0x2e, 0x76, 0x53, 0x31, 0xb1, 0xbd, 0xf7, 0xf2, 0xde, 0xdd,
0xcb, 0x19, 0xe6, 0xdb, 0x4e, 0x19, 0x75, 0xf3, 0x41, 0xd4, 0xe8, 0x82, 0x31, 0xc6, 0x4c, 0xf2,
0x6b, 0x88, 0x9e, 0x2d, 0x40, 0x84, 0x48, 0xd6, 0x1b, 0x12, 0xc1, 0x65, 0xb0, 0x3a, 0xae, 0x18,
0xe3, 0x19, 0x84, 0xbb, 0x6e, 0x2d, 0x26, 0x2c, 0xf5, 0x30, 0xff, 0x09, 0x20, 0x7e, 0x92, 0xa6,
0xfb, 0xc6, 0x19, 0x4c, 0xda, 0xc6, 0xb9, 0x2d, 0xc2, 0x05, 0x24, 0x8d, 0xda, 0xd4, 0xad, 0x74,
0x76, 0xc7, 0xfc, 0x8c, 0x70, 0x3f, 0x03, 0xcf, 0x21, 0x36, 0xad, 0x59, 0x93, 0x88, 0x58, 0x1b,
0x08, 0x0a, 0x48, 0xdf, 0x95, 0x34, 0x24, 0x8d, 0x88, 0x59, 0xf7, 0xb4, 0x6f, 0xd6, 0xd4, 0x86,
0x44, 0x62, 0xe5, 0xb0, 0x62, 0x9c, 0x97, 0x00, 0x2f, 0xf4, 0x55, 0xd1, 0xe7, 0x8e, 0xb4, 0xf9,
0x67, 0xf7, 0x29, 0x64, 0x9c, 0xd1, 0x5b, 0x25, 0x35, 0xe5, 0x39, 0xcc, 0xfa, 0x3f, 0x69, 0x49,
0xfb, 0x31, 0x2e, 0x12, 0x8c, 0x91, 0x3b, 0x38, 0xdd, 0x7b, 0x86, 0x18, 0x5e, 0x41, 0x4a, 0x83,
0x64, 0x8d, 0xe1, 0x2a, 0x2b, 0x4f, 0x8a, 0xe1, 0xaa, 0x7c, 0x96, 0xca, 0x7f, 0x2c, 0x35, 0xc4,
0xfd, 0x5d, 0x35, 0x16, 0x10, 0xda, 0xb5, 0x38, 0x77, 0xb6, 0xb1, 0xf6, 0x12, 0x0f, 0x25, 0xd7,
0xea, 0x08, 0xef, 0x21, 0x75, 0x3b, 0xf1, 0xe2, 0x60, 0xf4, 0xd8, 0x73, 0xb9, 0xf8, 0x2b, 0xfb,
0xec, 0xe3, 0xf4, 0x35, 0xe3, 0xc7, 0x7d, 0x60, 0xc3, 0x5b, 0xc2, 0xe4, 0xf6, 0x37, 0x00, 0x00,
0xff, 0xff, 0x66, 0x49, 0x14, 0x45, 0xfe, 0x01, 0x00, 0x00,
}

View File

@@ -1,110 +0,0 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/feeds.proto
package feeds
import (
fmt "fmt"
proto "github.com/golang/protobuf/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 Feeds service
func NewFeedsEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Feeds service
type FeedsService interface {
New(ctx context.Context, in *NewRequest, opts ...client.CallOption) (*NewResponse, error)
Entries(ctx context.Context, in *EntriesRequest, opts ...client.CallOption) (*EntriesResponse, error)
}
type feedsService struct {
c client.Client
name string
}
func NewFeedsService(name string, c client.Client) FeedsService {
return &feedsService{
c: c,
name: name,
}
}
func (c *feedsService) New(ctx context.Context, in *NewRequest, opts ...client.CallOption) (*NewResponse, error) {
req := c.c.NewRequest(c.name, "Feeds.New", in)
out := new(NewResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *feedsService) Entries(ctx context.Context, in *EntriesRequest, opts ...client.CallOption) (*EntriesResponse, error) {
req := c.c.NewRequest(c.name, "Feeds.Entries", in)
out := new(EntriesResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Feeds service
type FeedsHandler interface {
New(context.Context, *NewRequest, *NewResponse) error
Entries(context.Context, *EntriesRequest, *EntriesResponse) error
}
func RegisterFeedsHandler(s server.Server, hdlr FeedsHandler, opts ...server.HandlerOption) error {
type feeds interface {
New(ctx context.Context, in *NewRequest, out *NewResponse) error
Entries(ctx context.Context, in *EntriesRequest, out *EntriesResponse) error
}
type Feeds struct {
feeds
}
h := &feedsHandler{hdlr}
return s.Handle(s.NewHandler(&Feeds{h}, opts...))
}
type feedsHandler struct {
FeedsHandler
}
func (h *feedsHandler) New(ctx context.Context, in *NewRequest, out *NewResponse) error {
return h.FeedsHandler.New(ctx, in, out)
}
func (h *feedsHandler) Entries(ctx context.Context, in *EntriesRequest, out *EntriesResponse) error {
return h.FeedsHandler.Entries(ctx, in, out)
}

View File

@@ -1,42 +0,0 @@
syntax = "proto3";
package feeds;
option go_package = "proto;feeds";
service Feeds {
rpc New(NewRequest) returns (NewResponse) {}
rpc Entries(EntriesRequest) returns (EntriesResponse) {}
}
message Feed {
// rss feed name
string name = 1;
// rss feed url
string url = 2;
}
message Entry {
string id = 1;
string domain = 2;
string url = 3;
string title = 4;
string content = 5;
int64 date = 6;
}
message NewRequest {
string name = 1;
string url = 2;
}
message NewResponse {
}
message EntriesRequest {
string url = 1;
}
message EntriesResponse {
repeated Entry entries = 1;
}

View File

@@ -3,10 +3,10 @@ package handler
import (
"context"
comments "github.com/micro/services/blog/comments/proto"
posts "github.com/micro/services/blog/posts/proto"
comments "github.com/micro/services/comments/proto"
posts "github.com/micro/services/posts/proto"
proto "github.com/micro/services/blog/proto"
tags "github.com/micro/services/blog/tags/proto"
tags "github.com/micro/services/tags/proto"
)
type Blog struct {

View File

@@ -1,11 +1,11 @@
package main
import (
comments "github.com/micro/services/blog/comments/proto"
comments "github.com/micro/services/comments/proto"
"github.com/micro/services/blog/handler"
posts "github.com/micro/services/blog/posts/proto"
posts "github.com/micro/services/posts/proto"
proto "github.com/micro/services/blog/proto"
tags "github.com/micro/services/blog/tags/proto"
tags "github.com/micro/services/tags/proto"
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"

View File

@@ -1,2 +0,0 @@
./posts

View File

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

View File

@@ -1,22 +0,0 @@
GOPATH:=$(shell go env GOPATH)
MODIFY=Mgithub.com/micro/micro/proto/api/api.proto=github.com/micro/micro/v3/proto/api
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=${MODIFY}:. --go_out=${MODIFY}:. proto/posts.proto
.PHONY: build
build: proto
go build -o post-service *.go
.PHONY: test
test:
go test -v ./... -cover
.PHONY: docker
docker:
docker build . -t post-service:latest

View File

@@ -1,32 +0,0 @@
# Post Service
The posts service stores posts
## Usage
### Create a post
```
micro call posts Posts.Save '{"post":{"id":"1","title":"How to Micro","content":"Simply put, Micro is awesome."}}'
micro call posts Posts.Save '{"post":{"id":"2","title":"Fresh posts are fresh","content":"This post is fresher than the How to Micro one"}}'
```
### Create a post with tags
```
micro call posts Posts.Save '{"post":{"id":"3","title":"How to do epic things with Micro","content":"Everything is awesome.","tagNames":["a","b"]}}'
```
### Query posts
```
micro call posts Posts.Query '{}'
micro call posts Posts.Query '{"slug":"how-to-micro"}'
micro call posts Posts.Query '{"offset": 10, "limit": 10}'
```
### Delete posts
```
micro call posts Posts.Delete '{"offset": 10, "limit": 10}'
```

View File

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

View File

@@ -1,212 +0,0 @@
package handler
import (
"context"
"time"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/micro/v3/service/store"
"github.com/micro/dev/model"
"github.com/gosimple/slug"
proto "github.com/micro/services/blog/posts/proto"
tags "github.com/micro/services/blog/tags/proto"
)
const (
tagType = "post-tag"
)
type Posts struct {
Tags tags.TagsService
db model.Model
}
func NewPosts(tagsService tags.TagsService) *Posts {
createdIndex := model.ByEquality("created")
createdIndex.Order.Type = model.OrderTypeDesc
return &Posts{
Tags: tagsService,
db: model.New(
store.DefaultStore,
"posts",
model.Indexes(model.ByEquality("slug"), createdIndex),
&model.ModelOptions{
Debug: false,
},
),
}
}
func (p *Posts) Save(ctx context.Context, req *proto.SaveRequest, rsp *proto.SaveResponse) error {
if len(req.Id) == 0 {
return errors.BadRequest("proto.save.input-check", "Id is missing")
}
// read by 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("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 := &proto.Post{
Id: req.Id,
Title: req.Title,
Content: req.Content,
Tags: req.Tags,
Slug: postSlug,
Created: time.Now().Unix(),
Metadata: req.Metadata,
Image: req.Image,
}
err := p.savePost(ctx, nil, post)
if err != nil {
return errors.InternalServerError("proto.save.post-save", "Failed to save new post: %v", err.Error())
}
return nil
}
oldPost := posts[0]
post := &proto.Post{
Id: req.Id,
Title: oldPost.Title,
Content: oldPost.Content,
Slug: oldPost.Slug,
Tags: oldPost.Tags,
Created: oldPost.Created,
Updated: time.Now().Unix(),
Metadata: req.Metadata,
Image: req.Image,
}
if len(req.Title) > 0 {
post.Title = req.Title
post.Slug = slug.Make(post.Title)
}
if len(req.Slug) > 0 {
post.Slug = req.Slug
}
if len(req.Content) > 0 {
post.Content = req.Content
}
if len(req.Tags) > 0 {
// Handle the special case of deletion
if len(req.Tags) == 0 && req.Tags[0] == "" {
post.Tags = []string{}
} else {
post.Tags = req.Tags
}
}
postsWithThisSlug := []*proto.Post{}
err = p.db.List(model.Equals("slug", postSlug), &postsWithThisSlug)
if err != nil {
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("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 *proto.Post) error {
err := p.db.Save(post)
if err != nil {
return err
}
if oldPost == nil {
for _, tagName := range post.Tags {
_, err := p.Tags.Add(ctx, &tags.AddRequest{
ResourceID: post.Id,
Type: tagType,
Title: tagName,
})
if err != nil {
return err
}
}
return nil
}
return p.diffTags(ctx, post.Id, oldPost.Tags, post.Tags)
}
func (p *Posts) diffTags(ctx context.Context, parentID string, oldTagNames, newTagNames []string) error {
oldTags := map[string]struct{}{}
for _, v := range oldTagNames {
oldTags[v] = struct{}{}
}
newTags := map[string]struct{}{}
for _, v := range newTagNames {
newTags[v] = struct{}{}
}
for i := range oldTags {
_, stillThere := newTags[i]
if !stillThere {
_, err := p.Tags.Remove(ctx, &tags.RemoveRequest{
ResourceID: parentID,
Type: tagType,
Title: i,
})
if err != nil {
logger.Errorf("Error decreasing count for tag '%v' with type '%v' for parent '%v'", i, tagType, parentID)
}
}
}
for i := range newTags {
_, newlyAdded := oldTags[i]
if newlyAdded {
_, err := p.Tags.Add(ctx, &tags.AddRequest{
ResourceID: parentID,
Type: tagType,
Title: i,
})
if err != nil {
logger.Errorf("Error increasing count for tag '%v' with type '%v' for parent '%v': %v", i, tagType, parentID, err)
}
}
}
return nil
}
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)
q = model.Equals("slug", req.Slug)
} else if len(req.Id) > 0 {
logger.Infof("Reading post by id: %v", req.Id)
q = model.Equals("id", req.Id)
q.Order.Type = model.OrderTypeUnordered
} else {
q = model.Equals("created", nil)
q.Order.Type = model.OrderTypeDesc
var limit uint
limit = 20
if req.Limit > 0 {
limit = uint(req.Limit)
}
q.Limit = int64(limit)
q.Offset = req.Offset
logger.Infof("Listing posts, offset: %v, limit: %v", req.Offset, limit)
}
return p.db.List(q, &rsp.Posts)
}
func (p *Posts) Delete(ctx context.Context, req *proto.DeleteRequest, rsp *proto.DeleteResponse) error {
logger.Info("Received Post.Delete request")
q := model.Equals("id", req.Id)
q.Order.Type = model.OrderTypeUnordered
return p.db.Delete(q)
}

View File

@@ -1,25 +0,0 @@
package main
import (
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/services/blog/posts/handler"
tags "github.com/micro/services/blog/tags/proto"
)
func main() {
// Create the service
srv := service.New(
service.Name("posts"),
)
// Register Handler
srv.Handle(handler.NewPosts(
tags.NewTagsService("tags", srv.Client()),
))
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}

View File

@@ -1 +0,0 @@
service posts

View File

@@ -1,498 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: proto/posts.proto
package posts
import (
fmt "fmt"
proto "github.com/golang/protobuf/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 Post struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
Slug string `protobuf:"bytes,3,opt,name=slug,proto3" json:"slug,omitempty"`
Content string `protobuf:"bytes,4,opt,name=content,proto3" json:"content,omitempty"`
Created int64 `protobuf:"varint,5,opt,name=created,proto3" json:"created,omitempty"`
Updated int64 `protobuf:"varint,6,opt,name=updated,proto3" json:"updated,omitempty"`
Author string `protobuf:"bytes,7,opt,name=author,proto3" json:"author,omitempty"`
Tags []string `protobuf:"bytes,8,rep,name=tags,proto3" json:"tags,omitempty"`
Metadata map[string]string `protobuf:"bytes,9,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Image string `protobuf:"bytes,19,opt,name=image,proto3" json:"image,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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_e93dc7d934d9dc10, []int{0}
}
func (m *Post) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Post.Unmarshal(m, b)
}
func (m *Post) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Post.Marshal(b, m, deterministic)
}
func (m *Post) XXX_Merge(src proto.Message) {
xxx_messageInfo_Post.Merge(m, src)
}
func (m *Post) XXX_Size() int {
return xxx_messageInfo_Post.Size(m)
}
func (m *Post) XXX_DiscardUnknown() {
xxx_messageInfo_Post.DiscardUnknown(m)
}
var xxx_messageInfo_Post proto.InternalMessageInfo
func (m *Post) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Post) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func (m *Post) GetSlug() string {
if m != nil {
return m.Slug
}
return ""
}
func (m *Post) GetContent() string {
if m != nil {
return m.Content
}
return ""
}
func (m *Post) GetCreated() int64 {
if m != nil {
return m.Created
}
return 0
}
func (m *Post) GetUpdated() int64 {
if m != nil {
return m.Updated
}
return 0
}
func (m *Post) GetAuthor() string {
if m != nil {
return m.Author
}
return ""
}
func (m *Post) GetTags() []string {
if m != nil {
return m.Tags
}
return nil
}
func (m *Post) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
}
return nil
}
func (m *Post) GetImage() string {
if m != nil {
return m.Image
}
return ""
}
// Query posts. Acts as a listing when no id or slug provided.
// Gets a single post by id or slug if any of them provided.
type QueryRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Slug string `protobuf:"bytes,2,opt,name=slug,proto3" json:"slug,omitempty"`
Tag string `protobuf:"bytes,3,opt,name=tag,proto3" json:"tag,omitempty"`
Offset int64 `protobuf:"varint,4,opt,name=offset,proto3" json:"offset,omitempty"`
Limit int64 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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_e93dc7d934d9dc10, []int{1}
}
func (m *QueryRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryRequest.Unmarshal(m, b)
}
func (m *QueryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_QueryRequest.Marshal(b, m, deterministic)
}
func (m *QueryRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryRequest.Merge(m, src)
}
func (m *QueryRequest) XXX_Size() int {
return xxx_messageInfo_QueryRequest.Size(m)
}
func (m *QueryRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryRequest proto.InternalMessageInfo
func (m *QueryRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *QueryRequest) GetSlug() string {
if m != nil {
return m.Slug
}
return ""
}
func (m *QueryRequest) GetTag() string {
if m != nil {
return m.Tag
}
return ""
}
func (m *QueryRequest) GetOffset() int64 {
if m != nil {
return m.Offset
}
return 0
}
func (m *QueryRequest) GetLimit() int64 {
if m != nil {
return m.Limit
}
return 0
}
type QueryResponse struct {
Posts []*Post `protobuf:"bytes,1,rep,name=posts,proto3" json:"posts,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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_e93dc7d934d9dc10, []int{2}
}
func (m *QueryResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryResponse.Unmarshal(m, b)
}
func (m *QueryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_QueryResponse.Marshal(b, m, deterministic)
}
func (m *QueryResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryResponse.Merge(m, src)
}
func (m *QueryResponse) XXX_Size() int {
return xxx_messageInfo_QueryResponse.Size(m)
}
func (m *QueryResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryResponse proto.InternalMessageInfo
func (m *QueryResponse) GetPosts() []*Post {
if m != nil {
return m.Posts
}
return nil
}
type SaveRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
Slug string `protobuf:"bytes,3,opt,name=slug,proto3" json:"slug,omitempty"`
Content string `protobuf:"bytes,4,opt,name=content,proto3" json:"content,omitempty"`
Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// When updating a post and wanting to delete all tags,
// send a list of tags with only one member being an empty string [""]
Tags []string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty"`
Metadata map[string]string `protobuf:"bytes,7,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Image string `protobuf:"bytes,8,opt,name=image,proto3" json:"image,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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_e93dc7d934d9dc10, []int{3}
}
func (m *SaveRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SaveRequest.Unmarshal(m, b)
}
func (m *SaveRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SaveRequest.Marshal(b, m, deterministic)
}
func (m *SaveRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_SaveRequest.Merge(m, src)
}
func (m *SaveRequest) XXX_Size() int {
return xxx_messageInfo_SaveRequest.Size(m)
}
func (m *SaveRequest) XXX_DiscardUnknown() {
xxx_messageInfo_SaveRequest.DiscardUnknown(m)
}
var xxx_messageInfo_SaveRequest proto.InternalMessageInfo
func (m *SaveRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *SaveRequest) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func (m *SaveRequest) GetSlug() string {
if m != nil {
return m.Slug
}
return ""
}
func (m *SaveRequest) GetContent() string {
if m != nil {
return m.Content
}
return ""
}
func (m *SaveRequest) GetTimestamp() int64 {
if m != nil {
return m.Timestamp
}
return 0
}
func (m *SaveRequest) GetTags() []string {
if m != nil {
return m.Tags
}
return nil
}
func (m *SaveRequest) GetMetadata() map[string]string {
if m != nil {
return m.Metadata
}
return nil
}
func (m *SaveRequest) GetImage() string {
if m != nil {
return m.Image
}
return ""
}
type SaveResponse struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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_e93dc7d934d9dc10, []int{4}
}
func (m *SaveResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SaveResponse.Unmarshal(m, b)
}
func (m *SaveResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SaveResponse.Marshal(b, m, deterministic)
}
func (m *SaveResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_SaveResponse.Merge(m, src)
}
func (m *SaveResponse) XXX_Size() int {
return xxx_messageInfo_SaveResponse.Size(m)
}
func (m *SaveResponse) XXX_DiscardUnknown() {
xxx_messageInfo_SaveResponse.DiscardUnknown(m)
}
var xxx_messageInfo_SaveResponse proto.InternalMessageInfo
func (m *SaveResponse) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type DeleteRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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_e93dc7d934d9dc10, []int{5}
}
func (m *DeleteRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteRequest.Unmarshal(m, b)
}
func (m *DeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DeleteRequest.Marshal(b, m, deterministic)
}
func (m *DeleteRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_DeleteRequest.Merge(m, src)
}
func (m *DeleteRequest) XXX_Size() int {
return xxx_messageInfo_DeleteRequest.Size(m)
}
func (m *DeleteRequest) XXX_DiscardUnknown() {
xxx_messageInfo_DeleteRequest.DiscardUnknown(m)
}
var xxx_messageInfo_DeleteRequest proto.InternalMessageInfo
func (m *DeleteRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type DeleteResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
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_e93dc7d934d9dc10, []int{6}
}
func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DeleteResponse.Unmarshal(m, b)
}
func (m *DeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DeleteResponse.Marshal(b, m, deterministic)
}
func (m *DeleteResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_DeleteResponse.Merge(m, src)
}
func (m *DeleteResponse) XXX_Size() int {
return xxx_messageInfo_DeleteResponse.Size(m)
}
func (m *DeleteResponse) XXX_DiscardUnknown() {
xxx_messageInfo_DeleteResponse.DiscardUnknown(m)
}
var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo
func init() {
proto.RegisterType((*Post)(nil), "posts.Post")
proto.RegisterMapType((map[string]string)(nil), "posts.Post.MetadataEntry")
proto.RegisterType((*QueryRequest)(nil), "posts.QueryRequest")
proto.RegisterType((*QueryResponse)(nil), "posts.QueryResponse")
proto.RegisterType((*SaveRequest)(nil), "posts.SaveRequest")
proto.RegisterMapType((map[string]string)(nil), "posts.SaveRequest.MetadataEntry")
proto.RegisterType((*SaveResponse)(nil), "posts.SaveResponse")
proto.RegisterType((*DeleteRequest)(nil), "posts.DeleteRequest")
proto.RegisterType((*DeleteResponse)(nil), "posts.DeleteResponse")
}
func init() {
proto.RegisterFile("proto/posts.proto", fileDescriptor_e93dc7d934d9dc10)
}
var fileDescriptor_e93dc7d934d9dc10 = []byte{
// 447 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x54, 0xcb, 0xae, 0xd3, 0x40,
0x0c, 0x25, 0xcf, 0xb6, 0xee, 0xed, 0x55, 0x71, 0x0b, 0x1a, 0x22, 0x04, 0x25, 0x2b, 0x56, 0x45,
0x14, 0x10, 0x08, 0x58, 0xc2, 0x12, 0x09, 0xc2, 0x17, 0x0c, 0x74, 0x5a, 0x22, 0xf2, 0x22, 0x33,
0xa9, 0xd4, 0xff, 0x61, 0xc3, 0x7f, 0xf0, 0x61, 0xcc, 0x2b, 0x21, 0x29, 0x54, 0x77, 0xd3, 0x9d,
0x8f, 0x3d, 0xb6, 0x8f, 0xcf, 0x89, 0x02, 0xb7, 0xab, 0xba, 0x14, 0xe5, 0x93, 0xaa, 0xe4, 0x82,
0xaf, 0x75, 0x8c, 0x81, 0x06, 0xf1, 0x6f, 0x17, 0xfc, 0x8f, 0x32, 0xc2, 0x6b, 0x70, 0xd3, 0x2d,
0x71, 0x56, 0xce, 0xe3, 0x49, 0x22, 0x23, 0x5c, 0x42, 0x20, 0x52, 0x91, 0x31, 0xe2, 0xea, 0x94,
0x01, 0x88, 0xe0, 0xf3, 0xac, 0xd9, 0x13, 0x4f, 0x27, 0x75, 0x8c, 0x04, 0x46, 0x5f, 0xcb, 0x42,
0xb0, 0x42, 0x10, 0x5f, 0xa7, 0x5b, 0xa8, 0x2b, 0x35, 0xa3, 0x82, 0x6d, 0x49, 0x20, 0x2b, 0x5e,
0xd2, 0x42, 0x55, 0x69, 0xaa, 0xad, 0xae, 0x84, 0xa6, 0x62, 0x21, 0xde, 0x85, 0x90, 0x36, 0xe2,
0x5b, 0x59, 0x93, 0x91, 0x1e, 0x66, 0x91, 0xda, 0x2c, 0xe8, 0x9e, 0x93, 0xf1, 0xca, 0x53, 0x9b,
0x55, 0x8c, 0x2f, 0x60, 0x9c, 0x33, 0x41, 0x65, 0x23, 0x25, 0x13, 0x99, 0x9f, 0x6e, 0xee, 0xad,
0xcd, 0x8d, 0xea, 0xa4, 0xf5, 0x07, 0x5b, 0x7b, 0x5f, 0x88, 0xfa, 0x98, 0x74, 0x4f, 0xd5, 0x69,
0x69, 0x4e, 0xf7, 0x8c, 0x2c, 0xcc, 0x69, 0x1a, 0x44, 0x6f, 0x60, 0x36, 0x68, 0xc0, 0x39, 0x78,
0xdf, 0xd9, 0xd1, 0x4a, 0xa2, 0x42, 0xd5, 0x78, 0xa0, 0x59, 0xd3, 0x69, 0xa2, 0xc1, 0x6b, 0xf7,
0x95, 0x13, 0xd7, 0x70, 0xf5, 0xa9, 0x61, 0x72, 0x0b, 0xfb, 0xd1, 0xb0, 0xff, 0xa8, 0xd9, 0xea,
0xe6, 0xf6, 0x74, 0x93, 0xf3, 0xe5, 0x15, 0x56, 0x4a, 0x15, 0xaa, 0xdb, 0xcb, 0xdd, 0x8e, 0x33,
0x23, 0xa4, 0x97, 0x58, 0xa4, 0xf6, 0x66, 0x69, 0x9e, 0x0a, 0xab, 0xa2, 0x01, 0xf1, 0x06, 0x66,
0x76, 0x27, 0xaf, 0xca, 0x82, 0x33, 0x7c, 0x04, 0xc6, 0x54, 0xb9, 0x57, 0x69, 0x31, 0xed, 0x69,
0x91, 0x58, 0xbb, 0x7f, 0xba, 0x30, 0xfd, 0x4c, 0x0f, 0xec, 0x1c, 0xcf, 0x4b, 0xb8, 0x7e, 0x1f,
0x26, 0x22, 0xcd, 0xe5, 0x74, 0x9a, 0x57, 0x96, 0xf1, 0xdf, 0x44, 0xe7, 0x63, 0xd8, 0xf3, 0xf1,
0x6d, 0xcf, 0xc7, 0x91, 0xe6, 0xbe, 0xb2, 0xdc, 0x7b, 0x5c, 0x6f, 0xb6, 0x73, 0x7c, 0x31, 0x3b,
0x1f, 0xc0, 0x95, 0xd9, 0x6c, 0x95, 0x3d, 0x91, 0x29, 0x7e, 0x08, 0xb3, 0x77, 0x2c, 0x63, 0xe2,
0x9c, 0x8e, 0xf1, 0x1c, 0xae, 0xdb, 0x07, 0x66, 0xc4, 0xe6, 0x97, 0x03, 0x81, 0x72, 0x82, 0xe3,
0x73, 0x08, 0xb4, 0x6f, 0xb8, 0xb0, 0x47, 0xf6, 0xbf, 0x9c, 0x68, 0x39, 0x4c, 0x9a, 0xee, 0xf8,
0x16, 0x3e, 0x05, 0x5f, 0x51, 0x42, 0xfc, 0x57, 0x99, 0x68, 0x31, 0xc8, 0x75, 0x2d, 0x2f, 0x21,
0x34, 0x24, 0xb0, 0x1d, 0x3a, 0x20, 0x1d, 0xdd, 0x39, 0xc9, 0xb6, 0x8d, 0x5f, 0x42, 0xfd, 0x8b,
0x78, 0xf6, 0x27, 0x00, 0x00, 0xff, 0xff, 0x17, 0x84, 0x7a, 0xa4, 0x37, 0x04, 0x00, 0x00,
}

View File

@@ -1,129 +0,0 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/posts.proto
package posts
import (
fmt "fmt"
proto "github.com/golang/protobuf/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 Posts service
func NewPostsEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Posts service
type PostsService interface {
// Query currently only supports read by slug or timestamp, no listing.
Query(ctx context.Context, in *QueryRequest, opts ...client.CallOption) (*QueryResponse, error)
Save(ctx context.Context, in *SaveRequest, opts ...client.CallOption) (*SaveResponse, error)
Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error)
}
type postsService struct {
c client.Client
name string
}
func NewPostsService(name string, c client.Client) PostsService {
return &postsService{
c: c,
name: name,
}
}
func (c *postsService) Query(ctx context.Context, in *QueryRequest, opts ...client.CallOption) (*QueryResponse, error) {
req := c.c.NewRequest(c.name, "Posts.Query", in)
out := new(QueryResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *postsService) Save(ctx context.Context, in *SaveRequest, opts ...client.CallOption) (*SaveResponse, error) {
req := c.c.NewRequest(c.name, "Posts.Save", in)
out := new(SaveResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *postsService) Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) {
req := c.c.NewRequest(c.name, "Posts.Delete", in)
out := new(DeleteResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Posts service
type PostsHandler interface {
// Query currently only supports read by slug or timestamp, no listing.
Query(context.Context, *QueryRequest, *QueryResponse) error
Save(context.Context, *SaveRequest, *SaveResponse) error
Delete(context.Context, *DeleteRequest, *DeleteResponse) error
}
func RegisterPostsHandler(s server.Server, hdlr PostsHandler, opts ...server.HandlerOption) error {
type posts interface {
Query(ctx context.Context, in *QueryRequest, out *QueryResponse) error
Save(ctx context.Context, in *SaveRequest, out *SaveResponse) error
Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error
}
type Posts struct {
posts
}
h := &postsHandler{hdlr}
return s.Handle(s.NewHandler(&Posts{h}, opts...))
}
type postsHandler struct {
PostsHandler
}
func (h *postsHandler) Query(ctx context.Context, in *QueryRequest, out *QueryResponse) error {
return h.PostsHandler.Query(ctx, in, out)
}
func (h *postsHandler) Save(ctx context.Context, in *SaveRequest, out *SaveResponse) error {
return h.PostsHandler.Save(ctx, in, out)
}
func (h *postsHandler) Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error {
return h.PostsHandler.Delete(ctx, in, out)
}

View File

@@ -1,61 +0,0 @@
syntax = "proto3";
package posts;
service Posts {
// Query currently only supports read by slug or timestamp, no listing.
rpc Query(QueryRequest) returns (QueryResponse) {}
rpc Save(SaveRequest) returns (SaveResponse) {}
rpc Delete(DeleteRequest) returns (DeleteResponse) {}
}
message Post {
string id = 1;
string title = 2;
string slug = 3;
string content = 4;
int64 created = 5;
int64 updated = 6;
string author = 7;
repeated string tags = 8;
map<string,string> metadata = 9;
string image = 19;
}
// Query posts. Acts as a listing when no id or slug provided.
// Gets a single post by id or slug if any of them provided.
message QueryRequest {
string id = 1;
string slug = 2;
string tag = 3;
int64 offset = 4;
int64 limit = 5;
}
message QueryResponse {
repeated Post posts = 1;
}
message SaveRequest {
string id = 1;
string title = 2;
string slug = 3;
string content = 4;
int64 timestamp = 5;
// When updating a post and wanting to delete all tags,
// send a list of tags with only one member being an empty string [""]
repeated string tags = 6;
map<string,string> metadata = 7;
string image = 8;
}
message SaveResponse {
string id = 1;
}
message DeleteRequest {
string id = 1;
}
message DeleteResponse {}

View File

@@ -1,116 +1,211 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.6.1
// 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"
proto1 "github.com/micro/services/posts/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 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
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type LatestRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (m *LatestRequest) Reset() { *m = LatestRequest{} }
func (m *LatestRequest) String() string { return proto.CompactTextString(m) }
func (*LatestRequest) ProtoMessage() {}
func (x *LatestRequest) Reset() {
*x = LatestRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_blog_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LatestRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LatestRequest) ProtoMessage() {}
func (x *LatestRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_blog_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LatestRequest.ProtoReflect.Descriptor instead.
func (*LatestRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_fc5203cdc85000bc, []int{0}
return file_proto_blog_proto_rawDescGZIP(), []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:"-"`
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Latest *proto1.Post `protobuf:"bytes,1,opt,name=latest,proto3" json:"latest,omitempty"`
}
func (m *LatestResponse) Reset() { *m = LatestResponse{} }
func (m *LatestResponse) String() string { return proto.CompactTextString(m) }
func (*LatestResponse) ProtoMessage() {}
func (x *LatestResponse) Reset() {
*x = LatestResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_blog_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LatestResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LatestResponse) ProtoMessage() {}
func (x *LatestResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_blog_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LatestResponse.ProtoReflect.Descriptor instead.
func (*LatestResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_fc5203cdc85000bc, []int{1}
return file_proto_blog_proto_rawDescGZIP(), []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
func (x *LatestResponse) GetLatest() *proto1.Post {
if x != nil {
return x.Latest
}
return nil
}
func init() {
proto.RegisterType((*LatestRequest)(nil), "blog.LatestRequest")
proto.RegisterType((*LatestResponse)(nil), "blog.LatestResponse")
var File_proto_blog_proto protoreflect.FileDescriptor
var file_proto_blog_proto_rawDesc = []byte{
0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x04, 0x62, 0x6c, 0x6f, 0x67, 0x1a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x22, 0x0f, 0x0a, 0x0d, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x22, 0x35, 0x0a, 0x0e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2e, 0x50, 0x6f, 0x73, 0x74,
0x52, 0x06, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x32, 0x3d, 0x0a, 0x04, 0x42, 0x6c, 0x6f, 0x67,
0x12, 0x35, 0x0a, 0x06, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x13, 0x2e, 0x62, 0x6c, 0x6f,
0x67, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x14, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
func init() {
proto.RegisterFile("proto/blog.proto", fileDescriptor_fc5203cdc85000bc)
var (
file_proto_blog_proto_rawDescOnce sync.Once
file_proto_blog_proto_rawDescData = file_proto_blog_proto_rawDesc
)
func file_proto_blog_proto_rawDescGZIP() []byte {
file_proto_blog_proto_rawDescOnce.Do(func() {
file_proto_blog_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_blog_proto_rawDescData)
})
return file_proto_blog_proto_rawDescData
}
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,
var file_proto_blog_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_proto_blog_proto_goTypes = []interface{}{
(*LatestRequest)(nil), // 0: blog.LatestRequest
(*LatestResponse)(nil), // 1: blog.LatestResponse
(*proto1.Post)(nil), // 2: posts.Post
}
var file_proto_blog_proto_depIdxs = []int32{
2, // 0: blog.LatestResponse.latest:type_name -> posts.Post
0, // 1: blog.Blog.Latest:input_type -> blog.LatestRequest
1, // 2: blog.Blog.Latest:output_type -> blog.LatestResponse
2, // [2:3] is the sub-list for method output_type
1, // [1:2] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_proto_blog_proto_init() }
func file_proto_blog_proto_init() {
if File_proto_blog_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_blog_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LatestRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_blog_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LatestResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_blog_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_blog_proto_goTypes,
DependencyIndexes: file_proto_blog_proto_depIdxs,
MessageInfos: file_proto_blog_proto_msgTypes,
}.Build()
File_proto_blog_proto = out.File
file_proto_blog_proto_rawDesc = nil
file_proto_blog_proto_goTypes = nil
file_proto_blog_proto_depIdxs = nil
}

View File

@@ -6,7 +6,7 @@ package blog
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "github.com/micro/services/blog/posts/proto"
_ "github.com/micro/services/posts/proto"
math "math"
)

View File

@@ -1,8 +1,9 @@
syntax = "proto3";
package blog;
option go_package = "proto;blog";
import "github.com/micro/services/blog/posts/proto/posts.proto";
import "github.com/micro/services/posts/proto/posts.proto";
service Blog {
rpc Latest(LatestRequest) returns (LatestResponse) {}

0
blog/skip Normal file
View File

View File

@@ -1,2 +0,0 @@
./tags

View File

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

View File

@@ -1,22 +0,0 @@
GOPATH:=$(shell go env GOPATH)
MODIFY=Mgithub.com/micro/micro/proto/api/api.proto=github.com/micro/micro/v3/proto/api
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=${MODIFY}:. --go_out=${MODIFY}:. proto/tags.proto
.PHONY: build
build: proto
go build -o tag-service *.go
.PHONY: test
test:
go test -v ./... -cover
.PHONY: docker
docker:
docker build . -t tag-service:latest

View File

@@ -1,61 +0,0 @@
# Tag Service
This is the Tag service
## Query tags
```
micro tags list --type=post-tag
```
Generated with
```
micro new --namespace=go.micro --type=service tag
```
## Getting Started
- [Configuration](#configuration)
- [Dependencies](#dependencies)
- [Usage](#usage)
## Configuration
- FQDN: go.micro.service.tag
- Type: service
- Alias: tag
## Dependencies
Micro services depend on service discovery. The default is multicast DNS, a zeroconf system.
In the event you need a resilient multi-host setup we recommend etcd.
```
# install etcd
brew install etcd
# run etcd
etcd
```
## Usage
A Makefile is included for convenience
Build the binary
```
make build
```
Run the service
```
./tag-service
```
Build a docker image
```
make docker
```

View File

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

View File

@@ -1,223 +0,0 @@
package handler
import (
"context"
"encoding/json"
"fmt"
"github.com/gosimple/slug"
"github.com/micro/dev/model"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/micro/v3/service/store"
proto "github.com/micro/services/blog/tags/proto"
)
const (
resourcePrefix = "byResource"
tagCountPrefix = "tagCount"
childrenByTag = "childrenByTag"
)
type Tags struct {
db model.Model
}
func NewTags() *Tags {
slugIndex := model.ByEquality("slug")
slugIndex.Order.Type = model.OrderTypeUnordered
return &Tags{
db: model.New(
store.DefaultStore,
"tags",
model.Indexes(model.ByEquality("type")),
&model.ModelOptions{
IdIndex: slugIndex,
Debug: false,
},
),
}
}
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 := []*proto.Tag{}
tagSlug := slug.Make(req.GetTitle())
q := model.Equals("slug", tagSlug)
q.Order.Type = model.OrderTypeUnordered
err := t.db.List(q, &tags)
if err != nil {
return err
}
var tag *proto.Tag
// If no existing record is found, create a new one
if len(tags) == 0 {
tag = &proto.Tag{
Title: req.GetTitle(),
Type: req.Type,
Slug: tagSlug,
}
} else {
tag = tags[0]
}
// increase tag count
err = store.Write(&store.Record{
Key: fmt.Sprintf("%v:%v:%v", tagCountPrefix, tag.Slug, req.GetResourceID()),
Value: nil,
})
if err != nil {
return err
}
oldTagCount := tag.Count
// get tag count
recs, err := store.List(store.Prefix(fmt.Sprintf("%v:%v", tagCountPrefix, tag.Slug)), store.Limit(1000))
if err != nil {
return err
}
tag.Count = int64(len(recs))
if tag.Count == oldTagCount {
return fmt.Errorf("Tag count for tag %v is unchanged, was: %v, now: %v", tagSlug, oldTagCount, tag.Count)
}
tagJSON, err := json.Marshal(tag)
if err != nil {
return err
}
err = store.Write(&store.Record{
Key: fmt.Sprintf("%v:%v:%v", resourcePrefix, req.GetResourceID(), tag.Slug),
Value: tagJSON,
})
if err != nil {
return err
}
return t.saveTag(tag)
}
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 *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")
}
tagSlug := slug.Make(req.GetTitle())
resourceKey := fmt.Sprintf("%v:%v:%v", resourcePrefix, req.GetResourceID(), tagSlug)
// read by resource ID + slug, the record is identical in boths places anyway
records, err := store.Read(resourceKey)
if err != nil && err != store.ErrNotFound {
return err
}
// If no existing record is found, there is nothing to decrease
if len(records) == 0 {
// return error?
return nil
}
record := records[0]
tag := &proto.Tag{}
err = json.Unmarshal(record.Value, tag)
if err != nil {
return err
}
// decrease tag count
err = store.Delete(fmt.Sprintf("%v:%v:%v", tagCountPrefix, tag.Slug, req.GetResourceID()))
if err != nil {
return err
}
// get tag count
recs, err := store.List(store.Prefix(fmt.Sprintf("%v:%v", tagCountPrefix, tag.Slug)), store.Limit(1000))
if err != nil {
return err
}
tag.Count = int64(len(recs))
return t.saveTag(tag)
}
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
// and model here because model does not yet support
// many to many relations
key := ""
var q model.Query
if len(req.ResourceID) > 0 {
key = fmt.Sprintf("%v:%v", resourcePrefix, req.ResourceID)
} else if len(req.Type) > 0 {
q = model.Equals("type", req.Type)
} else {
return errors.BadRequest("tags.list.input-check", "resource id or type is required")
}
if q.Type != "" {
tags := []proto.Tag{}
err := t.db.List(q, &tags)
if err != nil {
return err
}
rsp.Tags = make([]*proto.Tag, len(tags))
for i, tag := range tags {
rsp.Tags[i] = &proto.Tag{
Title: tag.Title,
Type: tag.Type,
Slug: tag.Slug,
Count: tag.Count,
}
}
return nil
}
records, err := store.Read("", store.Prefix(key))
if err != nil {
return err
}
rsp.Tags = make([]*proto.Tag, len(records))
for i, record := range records {
tagRecord := &proto.Tag{}
err := json.Unmarshal(record.Value, tagRecord)
if err != nil {
return err
}
rsp.Tags[i] = &proto.Tag{
Title: tagRecord.Title,
Type: tagRecord.Type,
Slug: tagRecord.Slug,
Count: tagRecord.Count,
}
}
return nil
}
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 := []proto.Tag{}
q := model.Equals("slug", tagSlug)
q.Order.Type = model.OrderTypeUnordered
err := t.db.List(q, &tags)
if err != nil {
return err
}
if len(tags) == 0 {
return errors.BadRequest("tags.update.input-check", "Tag not found")
}
tags[0].Title = req.Title
return t.saveTag(&tags[0])
}

View File

@@ -1,23 +0,0 @@
package main
import (
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/services/blog/tags/handler"
)
func main() {
// Create service
srv := service.New(
service.Name("tags"),
)
// Register Handler
srv.Handle(handler.NewTags())
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}

View File

@@ -1 +0,0 @@
service tags

View File

@@ -1,510 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/micro/services/blog/tags/proto/tags.proto
package tags
import (
fmt "fmt"
proto "github.com/golang/protobuf/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 Tag struct {
// Type is useful for namespacing and listing across resources,
// ie. list tags for posts, customers etc.
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Slug string `protobuf:"bytes,2,opt,name=slug,proto3" json:"slug,omitempty"`
Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"`
Count int64 `protobuf:"varint,5,opt,name=count,proto3" json:"count,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Tag) Reset() { *m = Tag{} }
func (m *Tag) String() string { return proto.CompactTextString(m) }
func (*Tag) ProtoMessage() {}
func (*Tag) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{0}
}
func (m *Tag) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Tag.Unmarshal(m, b)
}
func (m *Tag) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Tag.Marshal(b, m, deterministic)
}
func (m *Tag) XXX_Merge(src proto.Message) {
xxx_messageInfo_Tag.Merge(m, src)
}
func (m *Tag) XXX_Size() int {
return xxx_messageInfo_Tag.Size(m)
}
func (m *Tag) XXX_DiscardUnknown() {
xxx_messageInfo_Tag.DiscardUnknown(m)
}
var xxx_messageInfo_Tag proto.InternalMessageInfo
func (m *Tag) GetType() string {
if m != nil {
return m.Type
}
return ""
}
func (m *Tag) GetSlug() string {
if m != nil {
return m.Slug
}
return ""
}
func (m *Tag) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func (m *Tag) GetDescription() string {
if m != nil {
return m.Description
}
return ""
}
func (m *Tag) GetCount() int64 {
if m != nil {
return m.Count
}
return 0
}
type AddRequest struct {
ResourceID string `protobuf:"bytes,1,opt,name=resourceID,proto3" json:"resourceID,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
ResourceCreated int64 `protobuf:"varint,4,opt,name=resourceCreated,proto3" json:"resourceCreated,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AddRequest) Reset() { *m = AddRequest{} }
func (m *AddRequest) String() string { return proto.CompactTextString(m) }
func (*AddRequest) ProtoMessage() {}
func (*AddRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{1}
}
func (m *AddRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddRequest.Unmarshal(m, b)
}
func (m *AddRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AddRequest.Marshal(b, m, deterministic)
}
func (m *AddRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_AddRequest.Merge(m, src)
}
func (m *AddRequest) XXX_Size() int {
return xxx_messageInfo_AddRequest.Size(m)
}
func (m *AddRequest) XXX_DiscardUnknown() {
xxx_messageInfo_AddRequest.DiscardUnknown(m)
}
var xxx_messageInfo_AddRequest proto.InternalMessageInfo
func (m *AddRequest) GetResourceID() string {
if m != nil {
return m.ResourceID
}
return ""
}
func (m *AddRequest) GetType() string {
if m != nil {
return m.Type
}
return ""
}
func (m *AddRequest) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func (m *AddRequest) GetResourceCreated() int64 {
if m != nil {
return m.ResourceCreated
}
return 0
}
type AddResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AddResponse) Reset() { *m = AddResponse{} }
func (m *AddResponse) String() string { return proto.CompactTextString(m) }
func (*AddResponse) ProtoMessage() {}
func (*AddResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{2}
}
func (m *AddResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddResponse.Unmarshal(m, b)
}
func (m *AddResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AddResponse.Marshal(b, m, deterministic)
}
func (m *AddResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_AddResponse.Merge(m, src)
}
func (m *AddResponse) XXX_Size() int {
return xxx_messageInfo_AddResponse.Size(m)
}
func (m *AddResponse) XXX_DiscardUnknown() {
xxx_messageInfo_AddResponse.DiscardUnknown(m)
}
var xxx_messageInfo_AddResponse proto.InternalMessageInfo
type RemoveRequest struct {
ResourceID string `protobuf:"bytes,1,opt,name=resourceID,proto3" json:"resourceID,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RemoveRequest) Reset() { *m = RemoveRequest{} }
func (m *RemoveRequest) String() string { return proto.CompactTextString(m) }
func (*RemoveRequest) ProtoMessage() {}
func (*RemoveRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{3}
}
func (m *RemoveRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RemoveRequest.Unmarshal(m, b)
}
func (m *RemoveRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RemoveRequest.Marshal(b, m, deterministic)
}
func (m *RemoveRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_RemoveRequest.Merge(m, src)
}
func (m *RemoveRequest) XXX_Size() int {
return xxx_messageInfo_RemoveRequest.Size(m)
}
func (m *RemoveRequest) XXX_DiscardUnknown() {
xxx_messageInfo_RemoveRequest.DiscardUnknown(m)
}
var xxx_messageInfo_RemoveRequest proto.InternalMessageInfo
func (m *RemoveRequest) GetResourceID() string {
if m != nil {
return m.ResourceID
}
return ""
}
func (m *RemoveRequest) GetType() string {
if m != nil {
return m.Type
}
return ""
}
func (m *RemoveRequest) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
type RemoveResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RemoveResponse) Reset() { *m = RemoveResponse{} }
func (m *RemoveResponse) String() string { return proto.CompactTextString(m) }
func (*RemoveResponse) ProtoMessage() {}
func (*RemoveResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{4}
}
func (m *RemoveResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RemoveResponse.Unmarshal(m, b)
}
func (m *RemoveResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RemoveResponse.Marshal(b, m, deterministic)
}
func (m *RemoveResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_RemoveResponse.Merge(m, src)
}
func (m *RemoveResponse) XXX_Size() int {
return xxx_messageInfo_RemoveResponse.Size(m)
}
func (m *RemoveResponse) XXX_DiscardUnknown() {
xxx_messageInfo_RemoveResponse.DiscardUnknown(m)
}
var xxx_messageInfo_RemoveResponse proto.InternalMessageInfo
type UpdateRequest struct {
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UpdateRequest) Reset() { *m = UpdateRequest{} }
func (m *UpdateRequest) String() string { return proto.CompactTextString(m) }
func (*UpdateRequest) ProtoMessage() {}
func (*UpdateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{5}
}
func (m *UpdateRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UpdateRequest.Unmarshal(m, b)
}
func (m *UpdateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UpdateRequest.Marshal(b, m, deterministic)
}
func (m *UpdateRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_UpdateRequest.Merge(m, src)
}
func (m *UpdateRequest) XXX_Size() int {
return xxx_messageInfo_UpdateRequest.Size(m)
}
func (m *UpdateRequest) XXX_DiscardUnknown() {
xxx_messageInfo_UpdateRequest.DiscardUnknown(m)
}
var xxx_messageInfo_UpdateRequest proto.InternalMessageInfo
func (m *UpdateRequest) GetType() string {
if m != nil {
return m.Type
}
return ""
}
func (m *UpdateRequest) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func (m *UpdateRequest) GetDescription() string {
if m != nil {
return m.Description
}
return ""
}
type UpdateResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UpdateResponse) Reset() { *m = UpdateResponse{} }
func (m *UpdateResponse) String() string { return proto.CompactTextString(m) }
func (*UpdateResponse) ProtoMessage() {}
func (*UpdateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{6}
}
func (m *UpdateResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UpdateResponse.Unmarshal(m, b)
}
func (m *UpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UpdateResponse.Marshal(b, m, deterministic)
}
func (m *UpdateResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_UpdateResponse.Merge(m, src)
}
func (m *UpdateResponse) XXX_Size() int {
return xxx_messageInfo_UpdateResponse.Size(m)
}
func (m *UpdateResponse) XXX_DiscardUnknown() {
xxx_messageInfo_UpdateResponse.DiscardUnknown(m)
}
var xxx_messageInfo_UpdateResponse proto.InternalMessageInfo
// ListRequest: list either by resource id or type.
// Optionally filter by min or max count.
type ListRequest struct {
ResourceID string `protobuf:"bytes,1,opt,name=resourceID,proto3" json:"resourceID,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
MinCount int64 `protobuf:"varint,3,opt,name=minCount,proto3" json:"minCount,omitempty"`
MaxCount int64 `protobuf:"varint,4,opt,name=maxCount,proto3" json:"maxCount,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListRequest) Reset() { *m = ListRequest{} }
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
func (*ListRequest) ProtoMessage() {}
func (*ListRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{7}
}
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListRequest.Unmarshal(m, b)
}
func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic)
}
func (m *ListRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListRequest.Merge(m, src)
}
func (m *ListRequest) XXX_Size() int {
return xxx_messageInfo_ListRequest.Size(m)
}
func (m *ListRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ListRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ListRequest proto.InternalMessageInfo
func (m *ListRequest) GetResourceID() string {
if m != nil {
return m.ResourceID
}
return ""
}
func (m *ListRequest) GetType() string {
if m != nil {
return m.Type
}
return ""
}
func (m *ListRequest) GetMinCount() int64 {
if m != nil {
return m.MinCount
}
return 0
}
func (m *ListRequest) GetMaxCount() int64 {
if m != nil {
return m.MaxCount
}
return 0
}
type ListResponse struct {
Tags []*Tag `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ListResponse) Reset() { *m = ListResponse{} }
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
func (*ListResponse) ProtoMessage() {}
func (*ListResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_fc76523216c4be8e, []int{8}
}
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListResponse.Unmarshal(m, b)
}
func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic)
}
func (m *ListResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ListResponse.Merge(m, src)
}
func (m *ListResponse) XXX_Size() int {
return xxx_messageInfo_ListResponse.Size(m)
}
func (m *ListResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ListResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ListResponse proto.InternalMessageInfo
func (m *ListResponse) GetTags() []*Tag {
if m != nil {
return m.Tags
}
return nil
}
func init() {
proto.RegisterType((*Tag)(nil), "tags.Tag")
proto.RegisterType((*AddRequest)(nil), "tags.AddRequest")
proto.RegisterType((*AddResponse)(nil), "tags.AddResponse")
proto.RegisterType((*RemoveRequest)(nil), "tags.RemoveRequest")
proto.RegisterType((*RemoveResponse)(nil), "tags.RemoveResponse")
proto.RegisterType((*UpdateRequest)(nil), "tags.UpdateRequest")
proto.RegisterType((*UpdateResponse)(nil), "tags.UpdateResponse")
proto.RegisterType((*ListRequest)(nil), "tags.ListRequest")
proto.RegisterType((*ListResponse)(nil), "tags.ListResponse")
}
func init() {
proto.RegisterFile("github.com/micro/services/blog/tags/proto/tags.proto", fileDescriptor_fc76523216c4be8e)
}
var fileDescriptor_fc76523216c4be8e = []byte{
// 406 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x53, 0x41, 0x4f, 0xab, 0x40,
0x10, 0x2e, 0x5d, 0xda, 0xbc, 0x0e, 0xaf, 0xef, 0xf5, 0xed, 0xeb, 0x81, 0x90, 0x68, 0x08, 0x27,
0x0e, 0x5a, 0x92, 0xaa, 0x3f, 0xa0, 0xa9, 0x17, 0x13, 0x4f, 0xa4, 0x1e, 0x8c, 0x27, 0x0a, 0x1b,
0xdc, 0xa4, 0xb0, 0xc8, 0x2e, 0x8d, 0x8d, 0x17, 0xff, 0xa3, 0x7f, 0xc8, 0xb0, 0x0b, 0xb8, 0xad,
0x8d, 0x17, 0xbd, 0xcd, 0x7c, 0xc3, 0xcc, 0xf7, 0xed, 0x37, 0x03, 0x5c, 0xa6, 0x54, 0x3c, 0x56,
0xeb, 0x59, 0xcc, 0xb2, 0x20, 0xa3, 0x71, 0xc9, 0x02, 0x4e, 0xca, 0x2d, 0x8d, 0x09, 0x0f, 0xd6,
0x1b, 0x96, 0x06, 0x22, 0x4a, 0x79, 0x50, 0x94, 0x4c, 0x30, 0x19, 0xce, 0x64, 0x88, 0xcd, 0x3a,
0xf6, 0x5e, 0x00, 0xad, 0xa2, 0x14, 0x63, 0x30, 0xc5, 0xae, 0x20, 0xb6, 0xe1, 0x1a, 0xfe, 0x28,
0x94, 0x71, 0x8d, 0xf1, 0x4d, 0x95, 0xda, 0x7d, 0x85, 0xd5, 0x31, 0x9e, 0xc2, 0x40, 0x50, 0xb1,
0x21, 0x36, 0x92, 0xa0, 0x4a, 0xb0, 0x0b, 0x56, 0x42, 0x78, 0x5c, 0xd2, 0x42, 0x50, 0x96, 0xdb,
0xa6, 0xac, 0xe9, 0x50, 0xdd, 0x17, 0xb3, 0x2a, 0x17, 0xf6, 0xc0, 0x35, 0x7c, 0x14, 0xaa, 0xc4,
0x7b, 0x35, 0x00, 0x16, 0x49, 0x12, 0x92, 0xa7, 0x8a, 0x70, 0x81, 0x4f, 0x01, 0x4a, 0xc2, 0x59,
0x55, 0xc6, 0xe4, 0xe6, 0xba, 0x91, 0xa2, 0x21, 0x9d, 0xc8, 0xbe, 0x26, 0xf2, 0xb8, 0x20, 0x1f,
0xfe, 0xb6, 0x7d, 0xcb, 0x92, 0x44, 0x82, 0x24, 0x52, 0x14, 0x0a, 0x0f, 0x61, 0x6f, 0x0c, 0x96,
0x54, 0xc0, 0x0b, 0x96, 0x73, 0xe2, 0xdd, 0xc3, 0x38, 0x24, 0x19, 0xdb, 0x92, 0x1f, 0xd7, 0xe4,
0x4d, 0xe0, 0x4f, 0x3b, 0xba, 0x21, 0x7b, 0x80, 0xf1, 0x5d, 0x91, 0x44, 0xa2, 0x23, 0x3b, 0xb6,
0x85, 0x6e, 0x58, 0xff, 0x0b, 0xc7, 0xd1, 0x27, 0xc7, 0x6b, 0xba, 0x76, 0x78, 0x43, 0xb7, 0x03,
0xeb, 0x96, 0x72, 0xf1, 0x9d, 0x97, 0x39, 0xf0, 0x2b, 0xa3, 0xf9, 0x52, 0x6e, 0x12, 0x49, 0x43,
0xbb, 0x5c, 0xd6, 0xa2, 0x67, 0x55, 0x33, 0x9b, 0x5a, 0x93, 0x7b, 0xe7, 0xf0, 0x5b, 0x51, 0x2b,
0x29, 0xf8, 0x04, 0xe4, 0xf5, 0xd9, 0x86, 0x8b, 0x7c, 0x6b, 0x3e, 0x9a, 0xc9, 0xb3, 0x5c, 0x45,
0x69, 0x28, 0xe1, 0xf9, 0x9b, 0x01, 0xe6, 0x2a, 0x4a, 0x39, 0x3e, 0x03, 0xb4, 0x48, 0x12, 0x3c,
0x51, 0x1f, 0x7c, 0x9c, 0x8a, 0xf3, 0x4f, 0x43, 0x9a, 0xe7, 0xf5, 0xf0, 0x15, 0x0c, 0x95, 0xc3,
0xf8, 0xbf, 0x2a, 0xef, 0xad, 0xd2, 0x99, 0xee, 0x83, 0x5d, 0x5b, 0x00, 0x66, 0x2d, 0x0e, 0x37,
0x33, 0x35, 0x8f, 0x1c, 0xac, 0x43, 0x3a, 0x8f, 0xb2, 0xb6, 0xe5, 0xd9, 0xdb, 0x62, 0xcb, 0x73,
0xe0, 0x7e, 0x6f, 0x3d, 0x94, 0xff, 0xdd, 0xc5, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0xb1,
0x3f, 0xea, 0xaf, 0x03, 0x00, 0x00,
}

View File

@@ -1,152 +0,0 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: github.com/micro/services/blog/tags/proto/tags.proto
package tags
import (
fmt "fmt"
proto "github.com/golang/protobuf/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 Tags service
func NewTagsEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Tags service
type TagsService interface {
// Add a tag to a resource
Add(ctx context.Context, in *AddRequest, opts ...client.CallOption) (*AddResponse, error)
// Remove a tag from a resource
Remove(ctx context.Context, in *RemoveRequest, opts ...client.CallOption) (*RemoveResponse, error)
// List tags by
List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error)
// Change properties of a tag, currently only the title and description
Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error)
}
type tagsService struct {
c client.Client
name string
}
func NewTagsService(name string, c client.Client) TagsService {
return &tagsService{
c: c,
name: name,
}
}
func (c *tagsService) Add(ctx context.Context, in *AddRequest, opts ...client.CallOption) (*AddResponse, error) {
req := c.c.NewRequest(c.name, "Tags.Add", in)
out := new(AddResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *tagsService) Remove(ctx context.Context, in *RemoveRequest, opts ...client.CallOption) (*RemoveResponse, error) {
req := c.c.NewRequest(c.name, "Tags.Remove", in)
out := new(RemoveResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *tagsService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) {
req := c.c.NewRequest(c.name, "Tags.List", in)
out := new(ListResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *tagsService) Update(ctx context.Context, in *UpdateRequest, opts ...client.CallOption) (*UpdateResponse, error) {
req := c.c.NewRequest(c.name, "Tags.Update", in)
out := new(UpdateResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Tags service
type TagsHandler interface {
// Add a tag to a resource
Add(context.Context, *AddRequest, *AddResponse) error
// Remove a tag from a resource
Remove(context.Context, *RemoveRequest, *RemoveResponse) error
// List tags by
List(context.Context, *ListRequest, *ListResponse) error
// Change properties of a tag, currently only the title and description
Update(context.Context, *UpdateRequest, *UpdateResponse) error
}
func RegisterTagsHandler(s server.Server, hdlr TagsHandler, opts ...server.HandlerOption) error {
type tags interface {
Add(ctx context.Context, in *AddRequest, out *AddResponse) error
Remove(ctx context.Context, in *RemoveRequest, out *RemoveResponse) error
List(ctx context.Context, in *ListRequest, out *ListResponse) error
Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error
}
type Tags struct {
tags
}
h := &tagsHandler{hdlr}
return s.Handle(s.NewHandler(&Tags{h}, opts...))
}
type tagsHandler struct {
TagsHandler
}
func (h *tagsHandler) Add(ctx context.Context, in *AddRequest, out *AddResponse) error {
return h.TagsHandler.Add(ctx, in, out)
}
func (h *tagsHandler) Remove(ctx context.Context, in *RemoveRequest, out *RemoveResponse) error {
return h.TagsHandler.Remove(ctx, in, out)
}
func (h *tagsHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error {
return h.TagsHandler.List(ctx, in, out)
}
func (h *tagsHandler) Update(ctx context.Context, in *UpdateRequest, out *UpdateResponse) error {
return h.TagsHandler.Update(ctx, in, out)
}

View File

@@ -1,63 +0,0 @@
syntax = "proto3";
package tags;
service Tags {
// Add a tag to a resource
rpc Add(AddRequest) returns (AddResponse) {}
// Remove a tag from a resource
rpc Remove(RemoveRequest) returns (RemoveResponse) {}
// List tags by
rpc List(ListRequest) returns (ListResponse) {}
// Change properties of a tag, currently only the title and description
rpc Update(UpdateRequest) returns (UpdateResponse){}
}
message Tag {
// Type is useful for namespacing and listing across resources,
// ie. list tags for posts, customers etc.
string type = 1;
string slug = 2;
string title = 3;
string description = 4;
int64 count = 5;
}
message AddRequest {
string resourceID = 1;
string type = 2;
string title = 3;
int64 resourceCreated = 4;
}
message AddResponse{}
message RemoveRequest {
string resourceID = 1;
string type = 2;
string title = 3;
}
message RemoveResponse{}
message UpdateRequest {
string type = 1;
string title = 2;
string description = 3;
}
message UpdateResponse{}
// ListRequest: list either by resource id or type.
// Optionally filter by min or max count.
message ListRequest{
string resourceID = 1;
string type = 2;
int64 minCount = 3;
int64 maxCount = 4;
}
message ListResponse{
repeated Tag tags = 1;
}