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
}
}