Slide 1

Slide 1 text

Challenge to Advanced API Architecture in Go Seiji Takahashi (@__timakin__ ) / Gunosy Inc. September 29th, 2017 golang.tokyo#9

Slide 2

Slide 2 text

About me • Seiji Takahashi • Github: timakin / Twitter: @__timakin__ • Gunosy Inc. Business Development Team • Go / Swift • Just a little bit contributed to Go.

Slide 3

Slide 3 text

Preface • Finding the sample projects of API server, based on maintainable and feature-rich Go code is so hard. • So I’ve tried to write an operable API server with plain and standard packages like 
 net/http on myself. • This is just the result of my best-effort challenge, and not the collective opinion of Go community.

Slide 4

Slide 4 text

Agenda • General problems when you write API server in Go. • Advanced API architecture in Go,
 which is adaptable for your production environment. • The introductions of simple & practical 
 packages you can use in your team tomorrow.

Slide 5

Slide 5 text

How do you write API in ɹɹ ɹɹ ʁ

Slide 6

Slide 6 text

How do you write API in Go? • Use Frameworks?

Slide 7

Slide 7 text

How do you write API in Go? • Use Frameworks? • echo / gin / goji / goa

Slide 8

Slide 8 text

How do you write API in Go? • Use Frameworks? • echo / gin / goji / goa • net/http

Slide 9

Slide 9 text

How do you write API in Go? • Use Frameworks? • echo / gin / goji / goa • net/http • Use ORMs?

Slide 10

Slide 10 text

How do you write API in Go? • Use Frameworks? • echo / gin / goji / goa • net/http • Use ORMs? • gorm / xorm / gorp / dbr

Slide 11

Slide 11 text

How do you write API in Go? • Use Frameworks? • echo / gin / goji / goa • net/http • Use ORMs? • gorm / xorm / gorp / dbr • database/sql

Slide 12

Slide 12 text

How do you write API in Go? • Use Frameworks? • echo / gin / goji / goa • net/http • Use ORMs? • gorm / xorm / gorp / dbr • database/sql • Which platform?

Slide 13

Slide 13 text

How do you write API in Go? • Use Frameworks? • echo / gin / goji / goa • net/http • Use ORMs? • gorm / xorm / gorp / dbr • database/sql • Which platform? • AWS / GCP

Slide 14

Slide 14 text

General problems when you write API server in Go • It’s easy to encounter circular import.

Slide 15

Slide 15 text

General problems when you write API server in Go • It’s easy to encounter circular import. • context.Context handling

Slide 16

Slide 16 text

General problems when you write API server in Go • It’s easy to encounter circular import. • context.Context handling • error handling

Slide 17

Slide 17 text

General problems when you write API server in Go • It’s easy to encounter circular import. • context.Context handling • error handling • Passing middleware objects without context.Context pollution

Slide 18

Slide 18 text

General problems when you write API server in Go • It’s easy to encounter circular import. • context.Context handling • error handling • Passing middleware objects without context.Context pollution • Mature Go hackers say “your shouldn’t use a framework. Just use net/http.”, however, it sounds there are too much stuff to do.

Slide 19

Slide 19 text

Any good sample?

Slide 20

Slide 20 text

Inspirations from goddd • marcusolsson/goddd

Slide 21

Slide 21 text

Inspirations from goddd • marcusolsson/goddd • Well-capsuled repository with Interface

Slide 22

Slide 22 text

Inspirations from goddd • marcusolsson/goddd • Well-capsuled repository with Interface • encoder / decoder for req / res payload.

Slide 23

Slide 23 text

Inspirations from goddd • marcusolsson/goddd • Well-capsuled repository with Interface • encoder / decoder for req / res payload. • DDD-based architecture enables you to easily avoid a circular import.

Slide 24

Slide 24 text

How to write API inspired by goddd with 
 plain packages?

Slide 25

Slide 25 text

Background • I wrote the sample project: “govod”. • Sorry, it’s a closed project because it includes some secrets.ʕ>ϖ<ʔ • Go video on demand API. • Deploy to Google App Engine • Features (≒ domains) • Authentication • Streaming

Slide 26

Slide 26 text

ex) /api/videos with paging interface

Slide 27

Slide 27 text

Directory tree Isolate main.go to app directory with 
 app.yaml (GAE config) to 
 avoid the go-app-builder error.

Slide 28

Slide 28 text

Directory tree `domain` and `repository` are main directories that have the business logics and data accessors. `middleware` has the http.Handler implementations. 


Slide 29

Slide 29 text

Inside of domain - Payload en/decoder - Error types - DI object - Business Logic - Interface of Repository - Routing - Paging token parset - etc…

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

Initializes the router with `gorilla/mux`

Slide 32

Slide 32 text

Combine middlewares for the simple declaration of http.Handler with `justinas/alice`. You can get stats with kicking the endpoint 
 “/api/stats” (`fukata/golang-stats-api-handler`)

Slide 33

Slide 33 text

Initialize repository, service (business logic), and dependency injector for HTTP Handler.

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

Declare the dependency injected to the custom handler. (If it’s not GAE `Dependency` may have `Logger`, or other middlewares…) Handler with DI enables you to handle middleware 
 without setting them in context.Context. 


Slide 36

Slide 36 text

Registration of the routings with CustomHandler and DI object.

Slide 37

Slide 37 text

Request handler with payload decoder/encoder. Decoder contains the validator. (`go-playground/validator.v9`) Response payload will be wrapped 
 with `unrolled/render`. It may results to return the error object given a detail context with `pkg/errors`

Slide 38

Slide 38 text

Paging token parser which returns pager cursor required by Datastore.

Slide 39

Slide 39 text

Call StreamingService with context and paging opts, and if it succeeded, return the encoded payload.

Slide 40

Slide 40 text

GetVideoCollection will return 1. videos 2. JWT which contains a pager cursor. 3. error JWT is generated by using `dgrijalva/jwt-go`

Slide 41

Slide 41 text

Access to data storage, with repository 
 which implements GetVideos.

Slide 42

Slide 42 text

Repository is an Interface. It hides which data adapter you depend on. This means you can define MockRepository and replace to them in test code.

Slide 43

Slide 43 text

Access to Datastore on Google Cloud Platform. (with `mjibson/goon`) You can switch the adapter to the clients of MySQL, Postgres, or in-memory database etc…

Slide 44

Slide 44 text

Conclusion • DDD-like architecture is good for Go API development. You can cleverly escape from hell of circular imports. • Repository Interface makes the way to access data pluggable. • In combination with some packages, 
 net/http is surely enough to implement API server. (But there are few samples so it looks hard at first.)

Slide 45

Slide 45 text

Thanks! • Questions? Come talk to me or 
 contact to the following accounts! • @__timakin__ • [email protected]