Messages Service

This commit is contained in:
Ben Toogood
2020-10-15 16:59:23 +01:00
parent 62918d0537
commit d5e5ea6012
10 changed files with 892 additions and 688 deletions

38
messages/README.md Normal file
View File

@@ -0,0 +1,38 @@
# Messages Service
The messages service is a simplified service for sending messages, much like email. You can send a message using the CLI:
```bash
> micro messages send --to=John --from=Barry --subject=HelloWorld --text="Hello John"
```
And then list the messages a user has recieved:
```bash
> micro messages list --user=John
{
"messages": [
{
"id": "78efd836-ca51-4163-af43-65985f7c6587",
"to": "John",
"from": "Barry",
"subject": "HelloWorld",
"text": "Hello John",
"sent_at": "1602777240"
}
]
}
```
Or lookup an individual email by ID:
```bash
> micro messages read --id=78efd836-ca51-4163-af43-65985f7c6587
{
"message": {
"id": "78efd836-ca51-4163-af43-65985f7c6587",
"to": "John",
"from": "Barry",
"subject": "HelloWorld",
"text": "Hello John",
"sent_at": "1602777240"
}
}
```

121
messages/handler/handler.go Normal file
View File

@@ -0,0 +1,121 @@
package handler
import (
"context"
"encoding/json"
"strings"
"time"
"github.com/google/uuid"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/store"
pb "github.com/micro/services/messages/proto"
)
const (
messagePrefix = "message"
joinKey = "/"
)
// New returns an initialized messages handler
func New() pb.MessagesHandler {
return new(handler)
}
type handler struct{}
// Send a message
func (h *handler) Send(ctx context.Context, req *pb.SendRequest, rsp *pb.SendResponse) error {
// validate the request
if len(req.To) == 0 {
return errors.BadRequest("messages.Send.MissingTo", "Missing to")
}
if len(req.From) == 0 {
return errors.BadRequest("messages.Send.MissingFrom", "Missing from")
}
if len(req.Text) == 0 {
return errors.BadRequest("messages.Send.MissingText", "Missing text")
}
// construct the message and marshal it to json
msg := &pb.Message{
Id: uuid.New().String(),
To: req.To,
From: req.From,
Subject: req.Subject,
Text: req.Text,
SentAt: time.Now().Unix(),
}
bytes, err := json.Marshal(msg)
if err != nil {
return errors.BadRequest("messages.Send.Unknown", "Error encoding message")
}
// write the message to the store under the recipients key
key := strings.Join([]string{messagePrefix, req.To, msg.Id}, joinKey)
if err := store.Write(&store.Record{Key: key, Value: bytes}); err != nil {
return errors.BadRequest("messages.Send.Unknown", "Error writing to the store")
}
// write the message to the store under the id (so it can be looked up without needing to know
// the users id)
key = strings.Join([]string{messagePrefix, msg.Id}, joinKey)
if err := store.Write(&store.Record{Key: key, Value: bytes}); err != nil {
return errors.BadRequest("messages.Send.Unknown", "Error writing to the store")
}
return nil
}
// List messages for a user
func (h *handler) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error {
// validate the request
if len(req.User) == 0 {
return errors.BadRequest("messages.List.MissingUser", "Missing user")
}
// query the store for any messages sent to the user
prefix := strings.Join([]string{messagePrefix, req.User}, joinKey)
recs, err := store.Read("", store.Prefix(prefix))
if err != nil {
return errors.BadRequest("messages.List.Unknown", "Error reading from the store")
}
// serialize the result
rsp.Messages = make([]*pb.Message, len(recs))
for i, r := range recs {
var msg pb.Message
if err := json.Unmarshal(r.Value, &msg); err != nil {
return errors.BadRequest("messages.List.Unknown", "Error decoding message")
}
rsp.Messages[i] = &msg
}
return nil
}
// Read a message
func (h *handler) Read(ctx context.Context, req *pb.ReadRequest, rsp *pb.ReadResponse) error {
// validate the request
if len(req.Id) == 0 {
return errors.BadRequest("messages.Read.MissingUser", "Missing user")
}
// query the store
key := strings.Join([]string{messagePrefix, req.Id}, joinKey)
recs, err := store.Read(key)
if err == store.ErrNotFound {
return errors.NotFound("message.Read.InvalidID", "Message not found with ID")
} else if err != nil {
return errors.BadRequest("messages.Read.Unknown", "Error reading from the store")
}
// serialize the response
var msg pb.Message
if err := json.Unmarshal(recs[0].Value, &msg); err != nil {
return errors.BadRequest("messages.Read.Unknown", "Error decoding message")
}
rsp.Message = &msg
return nil
}

View File

@@ -0,0 +1,390 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/micro/services/messages/proto/messages.proto
package messages
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 Message struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"`
From string `protobuf:"bytes,3,opt,name=from,proto3" json:"from,omitempty"`
Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"`
Text string `protobuf:"bytes,5,opt,name=text,proto3" json:"text,omitempty"`
SentAt int64 `protobuf:"varint,6,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Message) Reset() { *m = Message{} }
func (m *Message) String() string { return proto.CompactTextString(m) }
func (*Message) ProtoMessage() {}
func (*Message) Descriptor() ([]byte, []int) {
return fileDescriptor_926763a275409928, []int{0}
}
func (m *Message) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Message.Unmarshal(m, b)
}
func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Message.Marshal(b, m, deterministic)
}
func (m *Message) XXX_Merge(src proto.Message) {
xxx_messageInfo_Message.Merge(m, src)
}
func (m *Message) XXX_Size() int {
return xxx_messageInfo_Message.Size(m)
}
func (m *Message) XXX_DiscardUnknown() {
xxx_messageInfo_Message.DiscardUnknown(m)
}
var xxx_messageInfo_Message proto.InternalMessageInfo
func (m *Message) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Message) GetTo() string {
if m != nil {
return m.To
}
return ""
}
func (m *Message) GetFrom() string {
if m != nil {
return m.From
}
return ""
}
func (m *Message) GetSubject() string {
if m != nil {
return m.Subject
}
return ""
}
func (m *Message) GetText() string {
if m != nil {
return m.Text
}
return ""
}
func (m *Message) GetSentAt() int64 {
if m != nil {
return m.SentAt
}
return 0
}
type SendRequest struct {
To string `protobuf:"bytes,1,opt,name=to,proto3" json:"to,omitempty"`
From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"`
Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"`
Text string `protobuf:"bytes,4,opt,name=text,proto3" json:"text,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SendRequest) Reset() { *m = SendRequest{} }
func (m *SendRequest) String() string { return proto.CompactTextString(m) }
func (*SendRequest) ProtoMessage() {}
func (*SendRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_926763a275409928, []int{1}
}
func (m *SendRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendRequest.Unmarshal(m, b)
}
func (m *SendRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SendRequest.Marshal(b, m, deterministic)
}
func (m *SendRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_SendRequest.Merge(m, src)
}
func (m *SendRequest) XXX_Size() int {
return xxx_messageInfo_SendRequest.Size(m)
}
func (m *SendRequest) XXX_DiscardUnknown() {
xxx_messageInfo_SendRequest.DiscardUnknown(m)
}
var xxx_messageInfo_SendRequest proto.InternalMessageInfo
func (m *SendRequest) GetTo() string {
if m != nil {
return m.To
}
return ""
}
func (m *SendRequest) GetFrom() string {
if m != nil {
return m.From
}
return ""
}
func (m *SendRequest) GetSubject() string {
if m != nil {
return m.Subject
}
return ""
}
func (m *SendRequest) GetText() string {
if m != nil {
return m.Text
}
return ""
}
type SendResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SendResponse) Reset() { *m = SendResponse{} }
func (m *SendResponse) String() string { return proto.CompactTextString(m) }
func (*SendResponse) ProtoMessage() {}
func (*SendResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_926763a275409928, []int{2}
}
func (m *SendResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendResponse.Unmarshal(m, b)
}
func (m *SendResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SendResponse.Marshal(b, m, deterministic)
}
func (m *SendResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_SendResponse.Merge(m, src)
}
func (m *SendResponse) XXX_Size() int {
return xxx_messageInfo_SendResponse.Size(m)
}
func (m *SendResponse) XXX_DiscardUnknown() {
xxx_messageInfo_SendResponse.DiscardUnknown(m)
}
var xxx_messageInfo_SendResponse proto.InternalMessageInfo
type ListRequest struct {
User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,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_926763a275409928, []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) GetUser() string {
if m != nil {
return m.User
}
return ""
}
type ListResponse struct {
Messages []*Message `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,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_926763a275409928, []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) GetMessages() []*Message {
if m != nil {
return m.Messages
}
return nil
}
type ReadRequest 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 *ReadRequest) Reset() { *m = ReadRequest{} }
func (m *ReadRequest) String() string { return proto.CompactTextString(m) }
func (*ReadRequest) ProtoMessage() {}
func (*ReadRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_926763a275409928, []int{5}
}
func (m *ReadRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReadRequest.Unmarshal(m, b)
}
func (m *ReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReadRequest.Marshal(b, m, deterministic)
}
func (m *ReadRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReadRequest.Merge(m, src)
}
func (m *ReadRequest) XXX_Size() int {
return xxx_messageInfo_ReadRequest.Size(m)
}
func (m *ReadRequest) XXX_DiscardUnknown() {
xxx_messageInfo_ReadRequest.DiscardUnknown(m)
}
var xxx_messageInfo_ReadRequest proto.InternalMessageInfo
func (m *ReadRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type ReadResponse struct {
Message *Message `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReadResponse) Reset() { *m = ReadResponse{} }
func (m *ReadResponse) String() string { return proto.CompactTextString(m) }
func (*ReadResponse) ProtoMessage() {}
func (*ReadResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_926763a275409928, []int{6}
}
func (m *ReadResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReadResponse.Unmarshal(m, b)
}
func (m *ReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReadResponse.Marshal(b, m, deterministic)
}
func (m *ReadResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReadResponse.Merge(m, src)
}
func (m *ReadResponse) XXX_Size() int {
return xxx_messageInfo_ReadResponse.Size(m)
}
func (m *ReadResponse) XXX_DiscardUnknown() {
xxx_messageInfo_ReadResponse.DiscardUnknown(m)
}
var xxx_messageInfo_ReadResponse proto.InternalMessageInfo
func (m *ReadResponse) GetMessage() *Message {
if m != nil {
return m.Message
}
return nil
}
func init() {
proto.RegisterType((*Message)(nil), "messages.Message")
proto.RegisterType((*SendRequest)(nil), "messages.SendRequest")
proto.RegisterType((*SendResponse)(nil), "messages.SendResponse")
proto.RegisterType((*ListRequest)(nil), "messages.ListRequest")
proto.RegisterType((*ListResponse)(nil), "messages.ListResponse")
proto.RegisterType((*ReadRequest)(nil), "messages.ReadRequest")
proto.RegisterType((*ReadResponse)(nil), "messages.ReadResponse")
}
func init() {
proto.RegisterFile("github.com/micro/services/messages/proto/messages.proto", fileDescriptor_926763a275409928)
}
var fileDescriptor_926763a275409928 = []byte{
// 347 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0x4a, 0xf3, 0x40,
0x14, 0xc5, 0x99, 0x64, 0xbe, 0xa6, 0xdf, 0x4d, 0x29, 0x38, 0xa0, 0x0e, 0x82, 0x50, 0xb3, 0x2a,
0x88, 0x0d, 0xb6, 0x14, 0x17, 0xc5, 0x85, 0xae, 0x75, 0x13, 0x77, 0x6e, 0x4a, 0x9b, 0x8e, 0x35,
0x42, 0x3a, 0x35, 0x77, 0x22, 0x3e, 0x80, 0xef, 0xe3, 0x2b, 0xca, 0xfc, 0x49, 0x3b, 0x6a, 0x16,
0xee, 0xee, 0xef, 0xf6, 0x9e, 0x39, 0x3d, 0x87, 0xc0, 0xd5, 0xba, 0x50, 0xcf, 0xf5, 0x72, 0x94,
0xcb, 0x32, 0x2d, 0x8b, 0xbc, 0x92, 0x29, 0x8a, 0xea, 0xad, 0xc8, 0x05, 0xa6, 0xa5, 0x40, 0x5c,
0xac, 0x05, 0xa6, 0xdb, 0x4a, 0x2a, 0xb9, 0xc3, 0x91, 0x41, 0xd6, 0x6d, 0x38, 0xf9, 0x20, 0x10,
0xdd, 0x5b, 0x60, 0x7d, 0x08, 0x8a, 0x15, 0x27, 0x03, 0x32, 0xfc, 0x9f, 0x05, 0xc5, 0x4a, 0xb3,
0x92, 0x3c, 0xb0, 0xac, 0x24, 0x63, 0x40, 0x9f, 0x2a, 0x59, 0xf2, 0xd0, 0x6c, 0xcc, 0xcc, 0x38,
0x44, 0x58, 0x2f, 0x5f, 0x44, 0xae, 0x38, 0x35, 0xeb, 0x06, 0xf5, 0xb5, 0x12, 0xef, 0x8a, 0xff,
0xb3, 0xd7, 0x7a, 0x66, 0xc7, 0x10, 0xa1, 0xd8, 0xa8, 0xf9, 0x42, 0xf1, 0xce, 0x80, 0x0c, 0xc3,
0xac, 0xa3, 0xf1, 0x46, 0x25, 0x73, 0x88, 0x1f, 0xc4, 0x66, 0x95, 0x89, 0xd7, 0x5a, 0xa0, 0x72,
0xce, 0xe4, 0x97, 0x73, 0xd0, 0xee, 0x1c, 0xb6, 0x3b, 0xd3, 0xbd, 0x73, 0xd2, 0x87, 0x9e, 0x35,
0xc0, 0xad, 0xdc, 0xa0, 0x48, 0xce, 0x20, 0xbe, 0x2b, 0x50, 0x35, 0x86, 0x0c, 0x68, 0x8d, 0xa2,
0x72, 0x96, 0x66, 0x4e, 0xae, 0xa1, 0x67, 0x4f, 0xac, 0x84, 0x5d, 0xc0, 0xae, 0x36, 0x4e, 0x06,
0xe1, 0x30, 0x1e, 0x1f, 0x8c, 0x76, 0xbd, 0xba, 0x0e, 0xb3, 0x7d, 0xb3, 0xa7, 0x10, 0x67, 0x62,
0xe1, 0x47, 0xf2, 0xcb, 0x4d, 0x66, 0xd0, 0xb3, 0x3f, 0xbb, 0xd7, 0xcf, 0x21, 0x72, 0x52, 0x73,
0xd4, 0xfa, 0x78, 0x73, 0x31, 0xfe, 0x24, 0xd0, 0x75, 0x4b, 0x64, 0x53, 0xa0, 0x3a, 0x1a, 0x3b,
0xdc, 0x0b, 0xbc, 0x2e, 0x4f, 0x8e, 0x7e, 0xae, 0x9d, 0xe1, 0x14, 0xa8, 0x8e, 0xe7, 0xcb, 0xbc,
0x46, 0x7c, 0xd9, 0xb7, 0x16, 0xa6, 0x40, 0xf5, 0xff, 0xf6, 0x65, 0x5e, 0x4c, 0x5f, 0xe6, 0xc7,
0xbb, 0x9d, 0x3c, 0x5e, 0xfe, 0xf5, 0x63, 0x9d, 0x35, 0xb8, 0xec, 0x18, 0x9e, 0x7c, 0x05, 0x00,
0x00, 0xff, 0xff, 0x90, 0x20, 0xa1, 0xca, 0xe8, 0x02, 0x00, 0x00,
}

View File

@@ -0,0 +1,127 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: github.com/micro/services/messages/proto/messages.proto
package messages
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 Messages service
func NewMessagesEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Messages service
type MessagesService interface {
Send(ctx context.Context, in *SendRequest, opts ...client.CallOption) (*SendResponse, error)
List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error)
Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error)
}
type messagesService struct {
c client.Client
name string
}
func NewMessagesService(name string, c client.Client) MessagesService {
return &messagesService{
c: c,
name: name,
}
}
func (c *messagesService) Send(ctx context.Context, in *SendRequest, opts ...client.CallOption) (*SendResponse, error) {
req := c.c.NewRequest(c.name, "Messages.Send", in)
out := new(SendResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messagesService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) {
req := c.c.NewRequest(c.name, "Messages.List", in)
out := new(ListResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *messagesService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) {
req := c.c.NewRequest(c.name, "Messages.Read", in)
out := new(ReadResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Messages service
type MessagesHandler interface {
Send(context.Context, *SendRequest, *SendResponse) error
List(context.Context, *ListRequest, *ListResponse) error
Read(context.Context, *ReadRequest, *ReadResponse) error
}
func RegisterMessagesHandler(s server.Server, hdlr MessagesHandler, opts ...server.HandlerOption) error {
type messages interface {
Send(ctx context.Context, in *SendRequest, out *SendResponse) error
List(ctx context.Context, in *ListRequest, out *ListResponse) error
Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error
}
type Messages struct {
messages
}
h := &messagesHandler{hdlr}
return s.Handle(s.NewHandler(&Messages{h}, opts...))
}
type messagesHandler struct {
MessagesHandler
}
func (h *messagesHandler) Send(ctx context.Context, in *SendRequest, out *SendResponse) error {
return h.MessagesHandler.Send(ctx, in, out)
}
func (h *messagesHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error {
return h.MessagesHandler.List(ctx, in, out)
}
func (h *messagesHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error {
return h.MessagesHandler.Read(ctx, in, out)
}

View File

@@ -0,0 +1,44 @@
syntax = "proto3";
package messages;
option go_package = "github.com/micro/services/messages/proto;messages";
service Messages {
rpc Send(SendRequest) returns (SendResponse);
rpc List(ListRequest) returns (ListResponse);
rpc Read(ReadRequest) returns (ReadResponse);
}
message Message {
string id = 1;
string to = 2;
string from = 3;
string subject = 4;
string text = 5;
int64 sent_at = 6;
}
message SendRequest {
string to = 1;
string from = 2;
string subject = 3;
string text = 4;
}
message SendResponse {}
message ListRequest {
string user = 1;
}
message ListResponse {
repeated Message messages = 1;
}
message ReadRequest {
string id = 1;
}
message ReadResponse {
Message message = 1;
}