Skip to content

Instantly share code, notes, and snippets.

@murphysean
Last active August 29, 2015 14:06
Show Gist options
  • Save murphysean/2f7fd733a0ee620e9731 to your computer and use it in GitHub Desktop.
Save murphysean/2f7fd733a0ee620e9731 to your computer and use it in GitHub Desktop.
Go User MicroService
This is a sample dockerized go application that runs on port 8080
In order to run it, you'll want to go grab the mongodb image from docker
> sudo docker pull mongo:latest
Then you'll want to spin up an instance of the mongo container
> sudo docker run --name a-little-mongo -d mongo
Now that your mongodb is running, let's get this go app running
> go build
Ok, so now we have a binary in the dir of our app. Let's build an image of our app
> sudo docker build -t murphysean/ubuntu-go-usermicroservice:0.0.1 .
Now we are ready to fire up an instance of our application.
> sudo docker run -P -d --link a-little-mongo:db murphysean/ubuntu-go-usermicroservice:0.0.1
This go app is dependant on a host named 'db' that runs mongo on it's standard port
Notice how we linked the app to the running mongo instance through --link
This is cool cause we could have a few different mongos running, one for prod, one for dev
and we could control which one our app connects to through the --link command.
FROM ubuntu
MAINTAINER murphysean84@gmail.com
COPY . /app
# Install app dependencies
EXPOSE 8080
ENTRYPOINT ["/app/UserMicroService"]
package main
import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"code.google.com/p/go-uuid/uuid"
"github.com/gorilla/mux"
"net/http"
"encoding/json"
"fmt"
)
type User struct{
Id string `json:"id"`
Name string `json:"name,omitempty"`
}
var msession *mgo.Session
func GetUsersHandler(w http.ResponseWriter, r *http.Request){
fmt.Println("GetUsersHandler")
session := msession.Copy()
defer session.Close()
c := session.DB("test").C("users")
var users []User
key := r.URL.Query().Get("name")
if key == ""{
c.Find(bson.M{}).All(&users)
}else{
c.Find(bson.M{"name":key}).All(&users)
}
s,err := json.Marshal(users)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "Location")
w.Header().Set("Access-Control-Max-Age", "120")
w.Header().Set("Access-Control-Allow-Headers", "Origin, Accept, Content-Type, Authorization")
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE")
w.Header().Set("Content-Type","application/json")
w.Write(s)
}
func CreateUserHandler(w http.ResponseWriter, r *http.Request){
fmt.Println("CreateUserHandler")
uuid := uuid.NewRandom()
decoder := json.NewDecoder(r.Body)
var user User
err := decoder.Decode(&user)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
user.Id = uuid.String()
session := msession.Copy()
defer session.Close()
c := session.DB("test").C("users")
err = c.Insert(&user)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
s,err := json.Marshal(user)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(201)
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "Location")
w.Header().Set("Access-Control-Max-Age", "120")
w.Header().Set("Access-Control-Allow-Headers", "Origin, Accept, Content-Type, Authorization")
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE")
w.Header().Set("Content-Type","application/json")
w.Header().Set("Location",fmt.Sprint("/users/",user.Id))
w.Write(s)
}
func GetUserHandler(w http.ResponseWriter, r *http.Request){
fmt.Println("GetUserHandler")
vars := mux.Vars(r)
id := uuid.Parse(vars["id"])
if id == nil{
http.Error(w, "Couldn't parse UUID", http.StatusInternalServerError)
return
}
user := new(User)
user.Id = id.String()
session := msession.Copy()
defer session.Close()
c := session.DB("test").C("users")
err := c.Find(bson.M{"id":user.Id}).One(&user)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
s,err := json.Marshal(user)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "Location")
w.Header().Set("Access-Control-Max-Age", "120")
w.Header().Set("Access-Control-Allow-Headers", "Origin, Accept, Content-Type, Authorization")
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE")
w.Header().Set("Content-Type","application/json")
w.Write(s)
}
func UpdateUserHandler(w http.ResponseWriter, r *http.Request){
fmt.Println("UpdateUserHandler")
vars := mux.Vars(r)
id := uuid.Parse(vars["id"])
if id == nil{
http.Error(w, "Couldn't parse UUID", http.StatusInternalServerError)
return
}
decoder := json.NewDecoder(r.Body)
var user User
err := decoder.Decode(&user)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session := msession.Copy()
defer session.Close()
c := session.DB("test").C("users")
user.Id = id.String()
c.Update(bson.M{"id":user.Id}, bson.M{"$set": bson.M{"name":user.Name}})
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
s,err := json.Marshal(user)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "Location")
w.Header().Set("Access-Control-Max-Age", "120")
w.Header().Set("Access-Control-Allow-Headers", "Origin, Accept, Content-Type, Authorization")
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE")
w.Header().Set("Content-Type","application/json")
w.Write(s)
}
func DeleteUserHandler(w http.ResponseWriter, r *http.Request){
fmt.Println("DeleteUserHandler")
vars := mux.Vars(r)
id := uuid.Parse(vars["id"])
if id == nil{
http.Error(w, "Couldn't parse UUID", http.StatusInternalServerError)
return
}
session := msession.Copy()
defer session.Close()
c := session.DB("test").C("users")
err := c.Remove(bson.M{"id":id.String()})
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "Location")
w.Header().Set("Access-Control-Max-Age", "120")
w.Header().Set("Access-Control-Allow-Headers", "Origin, Accept, Content-Type, Authorization")
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE")
w.WriteHeader(204)
}
func OptionsHandler(w http.ResponseWriter, r *http.Request){
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "Location")
w.Header().Set("Access-Control-Max-Age", "120")
w.Header().Set("Access-Control-Allow-Headers", "Origin, Accept, Content-Type, Authorization")
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE")
w.WriteHeader(200)
}
func main(){
var err error;
msession, err = mgo.Dial("db")
if err != nil{
fmt.Println("Couldn't Connect to db")
panic(err)
}
msession.SetMode(mgo.Monotonic, true)
fmt.Println("Connected to MongoDB @db")
r := mux.NewRouter()
ur := r.PathPrefix("/users/").Subrouter()
ur.HandleFunc("/",OptionsHandler).Methods("OPTIONS")
ur.HandleFunc("/{id}",OptionsHandler).Methods("OPTIONS")
ur.HandleFunc("/",GetUsersHandler).Methods("GET")
ur.HandleFunc("/",CreateUserHandler).Methods("POST")
ur.HandleFunc("/{id}",GetUserHandler).Methods("GET")
ur.HandleFunc("/{id}",UpdateUserHandler).Methods("PUT")
ur.HandleFunc("/{id}",DeleteUserHandler).Methods("DELETE")
http.Handle("/", r)
fmt.Println("Now serving restfully on port 8080")
http.ListenAndServe(":8080",nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment