PM Team Server
Introduction
Build from the go-rest-api-template.
How to run
Compile and run using:
go build && ./pms-teamserver
The app will bind itself to port 3001 (defined in main.go
). If you
want to change it (e.g. bind it to the default http port 80), then use
the following environment variable PORT
(see main.go
). Same for
the location of the fixtures.json
model.
export PORT=80
export FIXTURES=/tmp/fixtures.json
Live Code Reloading
For live code reloading, use a task runner that automatically restarts
the server when it detects changes.
Install fresh:
go get github.com/pilu/fresh
Run by using the following command in your project root directory:
fresh
High-level Code Structure
Main server files (bootstrapping of http server):
main.go --> figure out application settings from various sources, start application context and kick the server
server.go --> actual server kicking is happening here: mainly loading of routes and middleware
Route definitions and handlers:
router.go --> server routes, e.g. GET /healthcheck, and binding of those routes to the correct route handlers
handlers.go --> defines the actual logic that gets executed when you visit a route and takes care of the response to the client
handlers_test.go --> tests for our route handlers
Data model descriptions and operations on the data:
models.go --> structs describing our data, bit similar to objects in other languages
database.go --> our mock/fake database implementation
database_test.go --> tests our mock/fake database
Test data in JSON format:
fixtures.json
Configuration file for [fresh](go get github.com/pilu/fresh):
runner.conf
Test that checks whether structs comply with the DataStorer interface:
interface_test.go
Helper structs and functions:
helpers.go
Defines application version using semantic versioning:
VERSION
Folder where we store all our go dependencies using the govendor
tool:
vendor/
Starting the application: main.go and server.go
The main entry point to our app is main.go
where we take care of the following:
Loading our environment variables, but also provide some default values that are useful when you run it on your local development machine:
var (
// try to read environment variables
env = os.Getenv("ENV") // LOCAL, DEV, STG, PRD
port = os.Getenv("PORT") // server traffic on this port
version = os.Getenv("VERSION") // path to VERSION file
fixtures = os.Getenv("FIXTURES") // path to fixtures file
)
if env == "" || env == local {
// check if we are running on our local machine, then set some default values
env = local
port = "3001"
version = "VERSION"
fixtures = "fixtures.json"
}
I'm using the environment variables technique to tell the app in what environment it lives:
LOCAL
: local development machine
DEV
: development or integration server
STG
: staging servers
PRD
: production servers
When it can't detect an environment variable, it assumes that it's running on your local development workstation.
We then load our version file. I have added a helper function in helpers.go
that can parse a VERSION
file using semantic versioning.
// reading version from file
version, err := ParseVersionFile(version)
if err != nil {
log.Fatal(err)
}
Data
Fixtures
API Routes