# Microservice - basic

[https://ewanvalentine.io](https://ewanvalentine.io/)

[https://yami.io/grpc/](https://yami.io/grpc/)

[http://callistaenterprise.se/blogg/teknik/2017/02/17/go-blog-series-part1/](http://callistaenterprise.se/blogg/teknik/2017/02/17/go-blog-series-part1/)

[https://ryanmccue.ca/creating-a-microservice-with-golang-and-goa/](https://ryanmccue.ca/creating-a-microservice-with-golang-and-goa/)

[https://yami.io/go-kit-example/](https://yami.io/go-kit-example/)

[http://btfak.com/微服务/2016/03/28/go-micro/](http://btfak.com/%E5%BE%AE%E6%9C%8D%E5%8A%A1/2016/03/28/go-micro/)

[https://wuyin.io/2018/02/22/learning-go-content-notes/](https://wuyin.io/2018/02/22/learning-go-content-notes/)

[https://wuyin.io/2018/03/07/50-shades-of-golang-traps-gotchas-mistakes/](https://wuyin.io/2018/03/07/50-shades-of-golang-traps-gotchas-mistakes/)

[https://blog.gopheracademy.com/advent-2017/go-grpc-beyond-basics/](https://blog.gopheracademy.com/advent-2017/go-grpc-beyond-basics/)

[https://wuyin.io/2018/05/10/microservices-part-1-introduction-and-consignment-service/](https://wuyin.io/2018/05/10/microservices-part-1-introduction-and-consignment-service/)

[https://github.com/astaxie/build-web-application-with-golang](https://github.com/astaxie/build-web-application-with-golang)

## BACKGROUND

### What is a Microservice?

traditional monolith application = organisations are grouped together within a single codebase.

microservice = independent runnable codebase.

| Scale (monolith)                                                                                                                | Scale (microservice)                    |
| ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| If your auth service is hit constantly, you need to scale the entire codebase to cope with the load for just your auth service. | scale individual services individually. |

### protobuf/gRPC

If communicates in traditional REST = service A has to encode its data into JSON/XML, send a large string over the wire, to service B, which then has to decode this message from JSON, back into code.

**What are protobuf and gPRC.**

gRPC = light-weight **binary** based RPC communication protocol

Protobuf = define an interface to your service using a developer friendly format. **protobuf is an interchange DSL of gRPC.**

![](https://479256487-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lq83Pz7lLypS9wG3q1j%2F-Lq83UhaSznRdzI5r9-V%2F-Lq83V8dQIm0mLs0wjQx%2FgRPC.png?generation=1569962730919437\&alt=media)

## WORKFLOW

### Install tools

```python
$ brew install protobuf

$ go get -u google.golang.org/grpc # install grpc framework
$ go get -u github.com/golang/protobuf/protoc-gen-go # install protobuf-for-go

$ go get -u github.com/micro/go-micro
```

### `.proto` file

```go
// shippy-play1/consignment-service/proto/consignment/consignment.proto

syntax = "proto3";
package go.micro.srv.consignment;

service ShippingService {
    rpc CreateConsignment (Consignment) returns (Response) {...}
    rpc GetConsignments (GetRequest) returns (Response) {...}
}

message Consignment {...}
message Container {...}
message Response {...}
message GetRequest {...}
```

Makefile

```
build:
    protoc \
        -I=$(GOPATH)/src/shippy-play1/consignment-srv/ \
        --go_out=plugins=grpc:$(GOPATH)/src/shippy-play1/consignment-srv/ \
        $(GOPATH)/src/shippy-play1/consignment-srv/proto/consignment/consignment.proto
```

generated `consignment-service/proto/consignment/consignment.pb.go`

```go
// defined by message
type Consignment struct {...}
type Container struct {...}
type Response struct {...}
type GetRequest struct {}

// - - - - - - - - - - - - - - - - - - - defined by service - Client 
// = = = interface = = =
type ShippingServiceClient interface {
    CreateConsignment(ctx context.Context, in *Consignment, opts ...grpc.CallOption) (*Response, error)
    GetConsignments(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*Response, error)
}
func NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient {}

// = = = struct = = =
type shippingServiceClient struct {...}
func (c *shippingServiceClient) CreateConsignment(ctx context.Context, in *Consignment, opts ...grpc.CallOption) (*Response, error) {}
func (c *shippingServiceClient) GetConsignments(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*Response, error) {}

// - - - - - - - - - - - - - - - - - - - defined by service - Server
type ShippingServiceServer interface {
    CreateConsignment(context.Context, *Consignment) (*Response, error)
    GetConsignments(context.Context, *GetRequest) (*Response, error)
}
func RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) {...}
```

### `pb.go` TL DR

```
# in .proto file
service XXX {
    rpc CreateConsignment (Consignment) returns (Response) {}
}

# in .pb.go file
type XXXClient interface {
    CreateConsignment(ctx context.Context, in *Consignment, opts ...grpc.CallOption) (*Response, error)
}

type XXXServer interface {
    CreateConsignment(context.Context, *Consignment) (*Response, error)
}

type XXXClient struct {
    cc *grpc.ClientConn
}
```

You have to define service struct by yourselves in `consignment-service/main.go`

```go
// = = = server struct = = =
type service struct {...}
func (s *service) CreateConsignment(ctx context.Context, req *pb.Consignment) (*pb.Response, error) {...}
func (s *service) GetConsignments(ctx context.Context, req *pb.GetRequest) (*pb.Response, error) {...}
```

### Docker

```
// build image with tag
$ docker build -t consignment-srv .
```

```
// comment CMD ["./consignment-srv"] inside Dockerfile
$ make build && make run

$ docker run -it consignment-srv
```
