README
¶
shared

A library of code that can be used in Go applications.
config
Reads in json key value pairs that are unmarshaled into one configuration struct that can be passed around through an application.
Example config/application.json
{
"name": "api",
"log_level": "info",
"port": 3000
}
Config - configuration that holds all configs.
type Config struct {
Application Application
Datasource Datasource
Dependents Dependents
}
This package relies on a directory that should be at the root of the application called config
. The Unmarshal() function looks for three json files named application.json
, datasource.json
and dependents.json
.
- config
- application.json // configs for Application struct
- datasource.json // configs for Datasource struct
- dependents.json // configs for Dependents struct
Application - configs for common application related objects.
type Application struct {
Name string `json:"application,omitempty"`
Port int `json:"port,omitempty"`
LogLevel string `json:"log_level,omitempty"`
Auth0 Auth0 `json:"auth0,omitempty"`
Auth0 - configurables for Auth0 middleware authentication.
type Auth0 struct {
Identifier string `json:"identifier,omitempty"`
Domain string `json:"domain,omitempty"`
}
Datasource - configurations for one or more mongo database objects.
type Datasource struct {
Mongo map[string]Mongo `json:"mongo,omitempty"`
type Mongo struct {
Collections map[string]string `json:"collections,omitempty"`
Database string `json:"database,omitempty"`
URI string `json:"uri,omitempty"`
}
Dependents - configurations for one or more api client objects.
type Dependents struct {
Client Client `json:"client,omitempty"`
Clients map[string]Client `json:"clients,omitempty"`
}
type Client struct {
Headers map[string]string `json:"headers,omitempty"`
Health string `json:"health,omitempty"`
URL string `json:"url,omitempty"`
Timeout int `json:"timeout,omitempty"`
}
client
Makes http client calls simpler while still allowing for customization for any CRUD application.
Client - client specific variables.
type Client struct {
Health string
Headers map[string]string
URL *url.URL
Client *http.Client
}
Response - dependent client responses.
type Response struct {
Status string
Code int
Body Body
}
type Body struct {
String string
Bytes []byte
IO io.Reader
}
client Set Up
For multiple clients, range over every client object keeping the same key and retrieving that key's values necessary to build a new client. For one client, do the same without ranging.
package main
import "github.com/jobaldw/shared/client"
func main() {
...
clients := make(map[string]client.Client)
for key, value := range conf.Dependents {
newClient, err := client.New(value.URL, value.Health, value.Timeout, value.Headers)
if err != nil {
return Controller{}, err
}
clients[key] = newClient
}
...
}
client Usage
http request
These http request all return a response.Response or an error.
func main() {
...
clients["key"].Get("path", params) /* or */ client.Get("path", params)
clients["key"].Put("path", params, body) /* or */ client.Put("path", params, body)
clients["key"].Post("path", params, body) /* or */ client.Post("path", params, body)
clients["key"].Delete("path", params) /* or */ client.Delete("path", params)
}
router
Utilizes the gorilla/mux routing and url matcher package. Primarily initializes a mux.Router with health and ready check endpoints and writes to the client.
Note: This package is dependent on the client package.
Resp - api client responses.
type Resp struct {
ID interface{} `json:"id,omitempty"`
Payload interface{} `json:"payload,omitempty"`
Status string `json:"status,omitempty"`
MSG string `json:"msg,omitempty"`
ERR string `json:"error,omitempty"`
ERRs string `json:"errors,omitempty"`
}
router Set Up
In order to use the router.New()
function, we will use the clients
created in the client section.
package main
import "github.com/jobaldw/shared/router"
func main() {
...
newRouter := router.New("api", clients) // see config to view "clients" declaration
}
router Usage
You can add as many endpoints as you want. Each instantiation needs a function to call and each function can have its own personalized response.
func main() {
...
newRouter.HandleFunc("/endpoint", foo()).Methods(http.MethodGet)
...
// starts the server and keeps it open
http.ListenAndServe(
8000,
r,
)
}
func foo() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
payload := struct{
ID string
}{
ID: "abc123",
}
resp := router.Resp{Status: "Up", MSG: "hello world", Payload: payload}
router.Response(w, 200, resp)
return
}
}
Output
The status of this response is 200 OK
{
"payload": {
"ID": "abc123"
},
"status": "Up",
"msg": "hello world"
}
middleware
Utilizes the auth0 middleware capability to validate user access to API endpoints using Bearer token authentication.
middleware Set Up
Note: You will need to set an environment variable named A0_DOMAIN
to your personal Auth0 domain and two additional environment variables for your client_id and client_secret.
package main
import "github.com/jobaldw/shared/config"
import "github.com/jobaldw/shared/middleware"
func main() {
...
// pass in configs.
middleware.New(conf.Application.Auth0.Domain, ENV_CLIENT_ID, ENV_CLIENT_SECRET)
...
// wrap function with middleware.Auth0() wrapper
newRouter.HandleFunc("/endpoint", middleware.Auth0(foo())).Methods(http.MethodGet)
...
http.ListenAndServe(
8000,
middleware.Handler(r), // wrap the router with the middle handler options
)
}
mgo
Utilizes the official mongo driver to make mongo request simpler.
Mongo - client configurations.
type Mongo struct {
Host string
Name string
User string
Collections map[string]string
Database *mongo.Database
URI *url.URL
}
mgo Set Up
import "github.com/jobaldw/shared/mgo"
func main() {
uri := "bW9uZ28rc3ZyOi8vZmFrZVVSTFBhdGhUb01vbmdv"
ds = mgo.Init(uri, "movieDB", map[string]string{"Act":"action", "Adv":"adventure", "Rom":"romance"})
if err := ds.Connect(); err != nil {
return ds, err
}
if err := ds.Ping(); err != nil {
return ds, err
}
}