Introducing MMO
Monorepo Microservice Orchestrator
Peter Malina
CTO @ FlowUp
Outline
- The Clean Architecture
- Microservices
- Monorepos
- CI & CD
- MMO
- Project scaffolding
- Generators
The Clean Architecture

Microservices (pros)
- Logic decoupling
- Smaller services
- Simpler to understand

Microservices (cons)
- Strict contracts between services
- Dependencies
- 200 deploy buttons
- ... and databases
- ... and caches
Deathstar architecture

Monorepos (pros)
- Easier testing
- No submodules needed
- Build feedback for whole repo
- Component sharing
- Refactoring
Monorepos (cons)
- Single CI pipeline
- Hard to maintain for large teams
- If master fails, everything fails
- May need more tooling
CI & CD
MMO
- Monorepo Microservice Orchestrator
- Scaffolding
- Code generation
- Plugins
- Still in Alpha :/
https://github.com/flowup/mmo
https://github.com/flowup/mmo-plugins
MMO
- Automating repetitive tasks
- Using gRPC as a communication protocol
go get -u github.com/flowup/mmoScaffolding - new project
$ mmo init myapp
$ tree myapp/
myapp/
├── LICENSE
├── mmo.yaml
├── README.md
└── .drone.ymlScaffolding - new Service
$ mmo add service book
$ tree book/
book/
├── cmd
│ └── book
│ └── main.go
├── deployment
│ └── deployment.yaml
├── protobuf
│ └── proto.proto
├── service.go
└── service_test.goPlugin Ecosystem
- flowup/mmo-gen-go-grpc - generates grpc from proto files
- flowup/mmo-gen-proto-interface - generates interface implementations from grpc
- flowup/mmo-gen-grpc-gateway - generates HTTP gateway from grpc
- flowup/mmo-gen-swagger - generates swagger from proto files
- flowup/mmo-gen-angular-client - generates angular client from proto files
mmo.yaml with plugins
name: myapp
plugins:
- flowup/mmo-gen-swagger:1.0.1
prefix: github.com/flowup/testbench/myapp
services:
book:
description: ""
plugins:
- flowup/mmo-gen-go-grpc:1.0.2
- flowup/mmo-gen-grpc-gateway:1.0.1Proto for every service
syntax = "proto3";
package book;
import "google/protobuf/empty.proto";
service BookService {
rpc GetVersion (google.protobuf.Empty) returns (Version) {}
rpc CreateBook(Book) returns (Book) {}
rpc GetAllBooks(google.protobuf.Empty) returns (Books) {}
}
message Version {
string name = 1;
}
message Book {
string name = 1;
string description = 2;
string author = 3;
}
message Books {
repeated Book books = 1;
}Proto for every service
// Service represents an implementation of the Book service interface
type Service struct {
}
// NewService creates a new service object
func NewService() *Service {
return &Service{}
}
// CreateBook creates a new book
func (s *Service) CreateBook(ctx context.Context, in *Book) (*Book, error) {
return in, nil
}HTTP Gateway
syntax = "proto3";
package book;
import "google/protobuf/empty.proto";
service BookService {
rpc CreateBook(Book) returns (Book) {
+ option (google.api.http) = {
+ post: "/v1/example/echo"
+ body: "*"
+ };
}
}
message Book {
string name = 1;
string description = 2;
string author = 3;
}gRPC SDKs
import "github.com/flowup/testbench/myapp/book"
type OtherService struct {
books *book.Service
}
func (s *OtherService) DoSomething(ctx context.Context, in *Model) (*Model, error) {
book, err := s.books.CreateBook(ctx, book.Book{.....})
...
}Thank you!
Questions?
Introducing MMO
By Peter Malina
Introducing MMO
- 392