![Page 1: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/1.jpg)
How To Structure Go ApplicationsPaul Bellamy
MILAN 25-26 NOVEMBER 2016
![Page 2: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/2.jpg)
![Page 3: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/3.jpg)
HOW BIG IS YOUR APPLICATION?
![Page 4: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/4.jpg)
GO DIFFERENCES
![Page 5: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/5.jpg)
META
![Page 6: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/6.jpg)
package privacy
type private struct{}
type Public struct {
PublicField string
privateField string
}
![Page 7: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/7.jpg)
IS GO AN OBJECT-ORIENTED LANGUAGE?
Go FAQ
![Page 8: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/8.jpg)
IS GO AN OBJECT-ORIENTED LANGUAGE? YES AND NO.
Go FAQ
![Page 9: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/9.jpg)
CAR
FIAT
![Page 10: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/10.jpg)
FIAT
CAR type Fiat struct {
Car
w Warranty
}
![Page 11: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/11.jpg)
![Page 12: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/12.jpg)
type Fiat struct {
Car
w Warranty
}
type Car struct{}
func (c Car) MarshalJSON() ([]byte, error) {
…
}
![Page 13: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/13.jpg)
![Page 14: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/14.jpg)
![Page 15: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/15.jpg)
~/GOPATH
![Page 16: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/16.jpg)
![Page 17: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/17.jpg)
FRAMEWORKS
![Page 18: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/18.jpg)
![Page 19: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/19.jpg)
# Get 'revel' framework and command
$ go get github.com/revel/cmd/revel
# Create a new app
$ revel new github.com/paulbellamy/myapp
# Run revel application
$ revel run github.com/paulbellamy/myapp
![Page 20: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/20.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
init.go Interceptor registration
models/ App domain models
routes/ Reverse routes (generated code)
views/ Templates
tests/ Test suites
conf/ Configuration files
app.conf Main configuration file
routes Routes definition
messages/ Message files
![Page 21: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/21.jpg)
WHAT WEAVE TRIED
![Page 22: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/22.jpg)
MVC
![Page 23: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/23.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
![Page 24: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/24.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
![Page 25: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/25.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
generate_certificates_tool.go
![Page 26: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/26.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
generate_certificates_tool.go
uuid.go
![Page 27: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/27.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
generate_certificates_tool.go
uuid.go
conn_with_read_timeout.go
![Page 28: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/28.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
generate_certificates_tool.go
uuid.go
conn_with_read_timeout.go
max_bytes_reader.go
![Page 29: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/29.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
generate_certificates_tool.go
uuid.go
conn_with_read_timeout.go
max_bytes_reader.go
time.go
![Page 30: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/30.jpg)
myapp/ App root
myapp.go App binary
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
generate_certificates_tool.go
uuid.go
conn_with_read_timeout.go
max_bytes_reader.go
![Page 31: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/31.jpg)
myapp/ App root
myapp.go App binary
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
generate_certificates_tool.go
uuid.go
conn_with_read_timeout.go
max_bytes_reader.go
![Page 33: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/33.jpg)
myapp/ App root
myapp.go App binary
app/ App sources
controllers/ App controllers
models/ App domain models
views/ Templates
public/ Public assets
lib/ Other stuff ???
generate_certificates_tool.go
uuid.go
conn_with_read_timeout.go
max_bytes_reader.go
![Page 34: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/34.jpg)
myapp/ App root
app/ App sources
controllers/ App controllers
users_controller.go
models/ App domain models
views/ Templates
![Page 35: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/35.jpg)
import "github.com/myaccount/myapp/app/controllers"
controllers.UsersController
![Page 36: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/36.jpg)
GROUP-BY-MODULE
![Page 37: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/37.jpg)
![Page 38: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/38.jpg)
scope/ App root
app/ Runs “in the cloud”
probe/ Runs in the users’s cluster
common/ Shared code between app and probe
xfer/ Defines the communication protocol
![Page 39: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/39.jpg)
scope/ App root
app/ Runs “in the cloud”
probe/ Runs in the users’s cluster
common/ Shared code between app and probe
xfer/ Defines the communication protocol
![Page 40: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/40.jpg)
scope/ App root
app/ Runs “in the cloud”
probe/ Runs in the users’s cluster
common/ Shared code between app and probe
xfer/ Defines the communication protocol
![Page 41: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/41.jpg)
scope/ App root
app/ Runs “in the cloud”
probe/ Runs in the users’s cluster
common/ Shared code between app and probe
xfer/ Defines the communication protocol
![Page 42: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/42.jpg)
BEST PRACTICE
![Page 43: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/43.jpg)
DOMAIN
![Page 44: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/44.jpg)
DOMAIN
ADAPTERS
![Page 45: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/45.jpg)
DOMAIN
ADAPTERS
BINARY
![Page 46: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/46.jpg)
DOMAIN
ADAPTERS
BINARY
![Page 47: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/47.jpg)
users/ App root
user.go
organization.go
errors.go
cmd/ App binaries
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
![Page 48: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/48.jpg)
users/ App root
README.md
Dockerfile
src/ Top-level container for go files
user.go
organization.go
errors.go
cmd/ App binaries
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
![Page 49: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/49.jpg)
// Without src/ directory
import "github.com/paulbellamy/users"
t := users.Organization{}
![Page 50: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/50.jpg)
// Without src/ directory
import "github.com/paulbellamy/users"
t := users.Organization{}
// With src/ directory
import users “github.com/paulbellamy/users/src"
t := users.Organization{}
![Page 51: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/51.jpg)
users/ App root
user.go
organization.go
errors.go
cmd/ App binaries
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
![Page 52: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/52.jpg)
users/ App root
add_user_to_organization.go
user.go
organization.go
errors.go
cmd/ App binaries
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
![Page 53: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/53.jpg)
// add_user_to_organization.go
package users
func AddUserToOrg(
db DB, email Emailer, userID, orgID string,
) error {
u, err := db.FindUser(userID) // make sure they exist
o, err := db.FindOrg(orgID)
db.AddUserToOrg(userID, orgID)
email.SendWelcomeEmail(u, o)
}
![Page 54: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/54.jpg)
package users
type DB interface {
FindUser(userID string) (User, error)
FindOrg(orgID string) (Organization, error)
AddUserToOrg(userID, orgID string) error
}
type Emailer interface {
SendWelcomeEmail(User, Organization) error
}
![Page 55: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/55.jpg)
users/ App root
add_user_to_organization.go
user.go
organization.go
errors.go
cmd/ App binaries
api/ HTTP API
emailer/ Email providers
smtp.go SMTP email provider
oauth/ OAuth Providers
db/ App database(s)
![Page 56: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/56.jpg)
package emailer
type SMTP struct {
server string
}
![Page 57: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/57.jpg)
package emailer
import "github.com/paulbellamy/users"
type SMTP struct {
server string
}
![Page 58: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/58.jpg)
package emailer
import "github.com/paulbellamy/users"
type SMTP struct {
server string
}
func (s SMTP) SendWelcomeEmail(
u users.User, o users.Organization,
) error {
return errors.New(“TODO”)
}
![Page 59: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/59.jpg)
users/ App root
add_user_to_organization.go
user.go
organization.go
errors.go
cmd/ App binaries
api/ HTTP API
http.go
emailer/ Email providers
smtp.go SMTP email provider
oauth/ OAuth Providers
db/ App database(s)
![Page 60: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/60.jpg)
package api
import "github.com/paulbellamy/users"
import "net/http"
type HTTP struct {
DB users.DB
Emailer users.Emailer
}
…
![Page 61: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/61.jpg)
…
func (h HTTP) ServeHTTP(
w http.ResponseWriter, r *http.Request,
) {
err := users.AddUserToOrganization(
h.DB, h.Emailer,
r.FormValue(“user_id”), r.FormValue(“org_id”),
)
}
![Page 62: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/62.jpg)
…
func (h HTTP) ServeHTTP(
w http.ResponseWriter, r *http.Request,
) {
err := users.AddUserToOrganization(
h.DB, h.Emailer,
r.FormValue(“user_id”), r.FormValue(“org_id”),
)
}
![Page 63: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/63.jpg)
…
func (h HTTP) ServeHTTP(
w http.ResponseWriter, r *http.Request,
) {
err := users.AddUserToOrganization(
h.DB, h.Emailer,
r.FormValue(“user_id”), r.FormValue(“org_id”),
)
}
![Page 64: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/64.jpg)
…
func (h HTTP) ServeHTTP(
w http.ResponseWriter, r *http.Request,
) {
err := users.AddUserToOrganization(
h.DB, h.Emailer,
r.FormValue(“user_id”), r.FormValue(“org_id”),
)
}
![Page 65: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/65.jpg)
users/ App root
add_user_to_organization.go
user.go
organization.go
errors.go
cmd/ App binaries
users/
main.go
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
![Page 66: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/66.jpg)
# Get 'revel' framework and command
$ go get github.com/revel/cmd/revel
# Create a new app
$ revel new github.com/paulbellamy/myapp
# Run revel application
$ revel run github.com/paulbellamy/myapp
![Page 67: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/67.jpg)
users/ App root
add_user_to_organization.go
user.go
organization.go
errors.go
cmd/ App binaries
users/
main.go
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
![Page 68: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/68.jpg)
// cmd/users/main.go
package main
func main() {
![Page 69: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/69.jpg)
// cmd/users/main.go
package main
import “net/http”
func main() {
http.ListenAndServe(“:8080”, a)
![Page 70: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/70.jpg)
// cmd/users/main.go
package main
import “github.com/paulbellamy/users/api”
import “net/http”
func main() {
a := api.HTTP{Emailer: e, DB: d}
http.ListenAndServe(“:8080”, a)
![Page 71: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/71.jpg)
// cmd/users/main.go
package main
import “github.com/paulbellamy/users/emailer”
import “github.com/paulbellamy/users/api”
import “net/http”
func main() {
e := emailer.SMTP{server: “smtp://mailcatcher.local”}
a := api.HTTP{db: d, emailer: e}
http.ListenAndServe(“:8080”, a)
![Page 72: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/72.jpg)
// cmd/users/main.go
package main
import “github.com/paulbellamy/users/emailer”
import “github.com/paulbellamy/users/db”
import “github.com/paulbellamy/users/api”
import “net/http”
func main() {
e := emailer.SMTP{server: “smtp://mailcatcher.local”}
d := db.New(databaseURL)
a := api.HTTP{db: d, emailer: e}
http.ListenAndServe(“:8080”, a)
![Page 73: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/73.jpg)
// cmd/users/main.go
package main
import “github.com/paulbellamy/users/emailer”
import “github.com/paulbellamy/users/db”
import “github.com/paulbellamy/users/api”
import “net/http”
func main() {
e := emailer.SMTP{server: “smtp://mailcatcher.local”}
d := db.New(databaseURL)
a := api.HTTP{db: d, emailer: e}
http.ListenAndServe(“:8080”, a)
![Page 74: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/74.jpg)
# Build our binary ready for deployment
$ go build github.com/paulbellamy/users/cmd/users
# Run our app
$ ./users
![Page 75: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/75.jpg)
users/ App root
cmd/ App binaries
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
mocks/ Testing mocks
emailer.go Mock emailer
db.go Mock db
![Page 76: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/76.jpg)
users/ App root
add_user_to_organization.go
user.go
organization.go
errors.go
cmd/ App binaries
users-server/ Server binary
users-client/ Client binary
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
![Page 77: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/77.jpg)
users/ App root
add_user_to_organization.go
user.go
organization.go
errors.go
cmd/ App binaries
api/ HTTP API
emailer/ Email providers
oauth/ OAuth Providers
db/ App database(s)
![Page 79: How To Structure Go Applications - Paul Bellamy - Codemotion Milan 2016](https://reader034.vdocument.in/reader034/viewer/2022052606/587080ce1a28ab57368b6563/html5/thumbnails/79.jpg)
SOCIALS
TWITTER: @PYRHHO GITHUB: PAULBELLAMY