-
-
Save nmerouze/2e26a02d23c4c62173fd to your computer and use it in GitHub Desktop.
| package main | |
| import ( | |
| "encoding/json" | |
| "log" | |
| "net/http" | |
| "reflect" | |
| "time" | |
| "github.com/gorilla/context" | |
| "github.com/julienschmidt/httprouter" | |
| "github.com/justinas/alice" | |
| "gopkg.in/mgo.v2" | |
| "gopkg.in/mgo.v2/bson" | |
| ) | |
| // Repo | |
| type Tea struct { | |
| Id bson.ObjectId `json:"id,omitempty" bson:"_id,omitempty"` | |
| Name string `json:"name"` | |
| Category string `json:"category"` | |
| } | |
| type TeasCollection struct { | |
| Data []Tea `json:"data"` | |
| } | |
| type TeaResource struct { | |
| Data Tea `json:"data"` | |
| } | |
| type TeaRepo struct { | |
| coll *mgo.Collection | |
| } | |
| func (r *TeaRepo) All() (TeasCollection, error) { | |
| result := TeasCollection{[]Tea{}} | |
| err := r.coll.Find(nil).All(&result.Data) | |
| if err != nil { | |
| return result, err | |
| } | |
| return result, nil | |
| } | |
| func (r *TeaRepo) Find(id string) (TeaResource, error) { | |
| result := TeaResource{} | |
| err := r.coll.FindId(bson.ObjectIdHex(id)).One(&result.Data) | |
| if err != nil { | |
| return result, err | |
| } | |
| return result, nil | |
| } | |
| func (r *TeaRepo) Create(tea *Tea) error { | |
| id := bson.NewObjectId() | |
| _, err := r.coll.UpsertId(id, tea) | |
| if err != nil { | |
| return err | |
| } | |
| tea.Id = id | |
| return nil | |
| } | |
| func (r *TeaRepo) Update(tea *Tea) error { | |
| err := r.coll.UpdateId(tea.Id, tea) | |
| if err != nil { | |
| return err | |
| } | |
| return nil | |
| } | |
| func (r *TeaRepo) Delete(id string) error { | |
| err := r.coll.RemoveId(bson.ObjectIdHex(id)) | |
| if err != nil { | |
| return err | |
| } | |
| return nil | |
| } | |
| // Errors | |
| type Errors struct { | |
| Errors []*Error `json:"errors"` | |
| } | |
| type Error struct { | |
| Id string `json:"id"` | |
| Status int `json:"status"` | |
| Title string `json:"title"` | |
| Detail string `json:"detail"` | |
| } | |
| func WriteError(w http.ResponseWriter, err *Error) { | |
| w.Header().Set("Content-Type", "application/vnd.api+json") | |
| w.WriteHeader(err.Status) | |
| json.NewEncoder(w).Encode(Errors{[]*Error{err}}) | |
| } | |
| var ( | |
| ErrBadRequest = &Error{"bad_request", 400, "Bad request", "Request body is not well-formed. It must be JSON."} | |
| ErrNotAcceptable = &Error{"not_acceptable", 406, "Not Acceptable", "Accept header must be set to 'application/vnd.api+json'."} | |
| ErrUnsupportedMediaType = &Error{"unsupported_media_type", 415, "Unsupported Media Type", "Content-Type header must be set to: 'application/vnd.api+json'."} | |
| ErrInternalServer = &Error{"internal_server_error", 500, "Internal Server Error", "Something went wrong."} | |
| ) | |
| // Middlewares | |
| func recoverHandler(next http.Handler) http.Handler { | |
| fn := func(w http.ResponseWriter, r *http.Request) { | |
| defer func() { | |
| if err := recover(); err != nil { | |
| log.Printf("panic: %+v", err) | |
| WriteError(w, ErrInternalServer) | |
| } | |
| }() | |
| next.ServeHTTP(w, r) | |
| } | |
| return http.HandlerFunc(fn) | |
| } | |
| func loggingHandler(next http.Handler) http.Handler { | |
| fn := func(w http.ResponseWriter, r *http.Request) { | |
| t1 := time.Now() | |
| next.ServeHTTP(w, r) | |
| t2 := time.Now() | |
| log.Printf("[%s] %q %v\n", r.Method, r.URL.String(), t2.Sub(t1)) | |
| } | |
| return http.HandlerFunc(fn) | |
| } | |
| func acceptHandler(next http.Handler) http.Handler { | |
| fn := func(w http.ResponseWriter, r *http.Request) { | |
| if r.Header.Get("Accept") != "application/vnd.api+json" { | |
| WriteError(w, ErrNotAcceptable) | |
| return | |
| } | |
| next.ServeHTTP(w, r) | |
| } | |
| return http.HandlerFunc(fn) | |
| } | |
| func contentTypeHandler(next http.Handler) http.Handler { | |
| fn := func(w http.ResponseWriter, r *http.Request) { | |
| if r.Header.Get("Content-Type") != "application/vnd.api+json" { | |
| WriteError(w, ErrUnsupportedMediaType) | |
| return | |
| } | |
| next.ServeHTTP(w, r) | |
| } | |
| return http.HandlerFunc(fn) | |
| } | |
| func bodyHandler(v interface{}) func(http.Handler) http.Handler { | |
| t := reflect.TypeOf(v) | |
| m := func(next http.Handler) http.Handler { | |
| fn := func(w http.ResponseWriter, r *http.Request) { | |
| val := reflect.New(t).Interface() | |
| err := json.NewDecoder(r.Body).Decode(val) | |
| if err != nil { | |
| WriteError(w, ErrBadRequest) | |
| return | |
| } | |
| if next != nil { | |
| context.Set(r, "body", val) | |
| next.ServeHTTP(w, r) | |
| } | |
| } | |
| return http.HandlerFunc(fn) | |
| } | |
| return m | |
| } | |
| // Main handlers | |
| type appContext struct { | |
| db *mgo.Database | |
| } | |
| func (c *appContext) teasHandler(w http.ResponseWriter, r *http.Request) { | |
| repo := TeaRepo{c.db.C("teas")} | |
| teas, err := repo.All() | |
| if err != nil { | |
| panic(err) | |
| } | |
| w.Header().Set("Content-Type", "application/vnd.api+json") | |
| json.NewEncoder(w).Encode(teas) | |
| } | |
| func (c *appContext) teaHandler(w http.ResponseWriter, r *http.Request) { | |
| params := context.Get(r, "params").(httprouter.Params) | |
| repo := TeaRepo{c.db.C("teas")} | |
| tea, err := repo.Find(params.ByName("id")) | |
| if err != nil { | |
| panic(err) | |
| } | |
| w.Header().Set("Content-Type", "application/vnd.api+json") | |
| json.NewEncoder(w).Encode(tea) | |
| } | |
| func (c *appContext) createTeaHandler(w http.ResponseWriter, r *http.Request) { | |
| body := context.Get(r, "body").(*TeaResource) | |
| repo := TeaRepo{c.db.C("teas")} | |
| err := repo.Create(&body.Data) | |
| if err != nil { | |
| panic(err) | |
| } | |
| w.Header().Set("Content-Type", "application/vnd.api+json") | |
| w.WriteHeader(201) | |
| json.NewEncoder(w).Encode(body) | |
| } | |
| func (c *appContext) updateTeaHandler(w http.ResponseWriter, r *http.Request) { | |
| params := context.Get(r, "params").(httprouter.Params) | |
| body := context.Get(r, "body").(*TeaResource) | |
| body.Data.Id = bson.ObjectIdHex(params.ByName("id")) | |
| repo := TeaRepo{c.db.C("teas")} | |
| err := repo.Update(&body.Data) | |
| if err != nil { | |
| panic(err) | |
| } | |
| w.WriteHeader(204) | |
| w.Write([]byte("\n")) | |
| } | |
| func (c *appContext) deleteTeaHandler(w http.ResponseWriter, r *http.Request) { | |
| params := context.Get(r, "params").(httprouter.Params) | |
| repo := TeaRepo{c.db.C("teas")} | |
| err := repo.Delete(params.ByName("id")) | |
| if err != nil { | |
| panic(err) | |
| } | |
| w.WriteHeader(204) | |
| w.Write([]byte("\n")) | |
| } | |
| // Router | |
| type router struct { | |
| *httprouter.Router | |
| } | |
| func (r *router) Get(path string, handler http.Handler) { | |
| r.GET(path, wrapHandler(handler)) | |
| } | |
| func (r *router) Post(path string, handler http.Handler) { | |
| r.POST(path, wrapHandler(handler)) | |
| } | |
| func (r *router) Put(path string, handler http.Handler) { | |
| r.PUT(path, wrapHandler(handler)) | |
| } | |
| func (r *router) Delete(path string, handler http.Handler) { | |
| r.DELETE(path, wrapHandler(handler)) | |
| } | |
| func NewRouter() *router { | |
| return &router{httprouter.New()} | |
| } | |
| func wrapHandler(h http.Handler) httprouter.Handle { | |
| return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { | |
| context.Set(r, "params", ps) | |
| h.ServeHTTP(w, r) | |
| } | |
| } | |
| func main() { | |
| session, err := mgo.Dial("localhost") | |
| if err != nil { | |
| panic(err) | |
| } | |
| defer session.Close() | |
| session.SetMode(mgo.Monotonic, true) | |
| appC := appContext{session.DB("test")} | |
| commonHandlers := alice.New(context.ClearHandler, loggingHandler, recoverHandler, acceptHandler) | |
| router := NewRouter() | |
| router.Get("/teas/:id", commonHandlers.ThenFunc(appC.teaHandler)) | |
| router.Put("/teas/:id", commonHandlers.Append(contentTypeHandler, bodyHandler(TeaResource{})).ThenFunc(appC.updateTeaHandler)) | |
| router.Delete("/teas/:id", commonHandlers.ThenFunc(appC.deleteTeaHandler)) | |
| router.Get("/teas", commonHandlers.ThenFunc(appC.teasHandler)) | |
| router.Post("/teas", commonHandlers.Append(contentTypeHandler, bodyHandler(TeaResource{})).ThenFunc(appC.createTeaHandler)) | |
| http.ListenAndServe(":8080", router) | |
| } |
@nmerouze out of interest have you moved on to Elixir?
Thanks for sharing!
please help, i have probeleum how to save consume api result to mongo
my code its error !!!
package main
import (
"encoding/json"
"fmt"
"bytes"
"io/ioutil"
"net/http"
//"mydb"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type Response struct {
StatusCode int json:"statusCode"
Headers map[string]string json:"headers"
Body string json:"body"
}
type Passanger struct {
bson.ObjectId json:"id" bson:"_id"
Title string json:"title" bson:"title"
Image string json:"image" bson:"image"
Price string json:"price" bson:"price"
Rating string json:"rating" bson:"rating"
}
//type Passanger struct {
//ID bson.ObjectId bson:"_id,omitempty"
//Title string
//Image string
//Price string
//Rating string
//}
var (
IsDrop = true
)
type Adapter func(http.Handler) http.Handler
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
for _, adapter := range adapters {
h = adapter(h)
}
return h
}
func main() {
fmt.Println("Starting the application...")
url := "http://"
fmt.Println("URL:>", url)
jsonData := map[string]string{}
jsonValue, _ := json.Marshal(jsonData)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonValue))
req.Header.Set("Content-Type", "application/json")
// req.Header.Set("Authorization", strAuthorization)
client := &http.Client{}
response, err := client.Do(req)
var info map[string]interface{}
var infodata string
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
} else {
data, _ := ioutil.ReadAll(response.Body)
//defer response.Body.Close()
//json.Unmarshal(data, &info)
fmt.Printf("ALTEA Response: %s\n", string(data))
}
fmt.Println("Save Data To Database...")
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
// Drop Database
if IsDrop {
err = session.DB("test").DropDatabase()
if err != nil {
panic(err)
}
}
// Collection Passanger
c := session.DB("flylist").C("passanger")
// Index
index := mgo.Index{
Key: []string{"title", "image", "price", "rating"},
Unique: true,
DropDups: true,
Background: true,
Sparse: true,
}
err = c.EnsureIndex(index)
if err != nil {
panic(err)
}
// Insert Datas
infodata = info["data"].(map[string]interface{})["id"].(string)
//konversi:= []byte(info)
err = c.Insert(&Passanger{Title: string(infodata[0]), Image: string(infodata[1]), Price: string(infodata[2]), Rating: string(infodata[3])})
if err != nil {
panic(err)
}
// Query All
var results []Passanger
err = c.Find(bson.M{"name": "Ale"}).Sort("-timestamp").All(&results)
if err != nil {
panic(err)
}
fmt.Println("Results All: ", results)
}
Please help Me ,!
Please help , i have problem when try to save consume api result to mongodb, the code it's error
package main
import (
"encoding/json"
"fmt"
"bytes"
"io/ioutil"
"net/http"
//"mydb"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type Response struct {
StatusCode int json:"statusCode"
Headers map[string]string json:"headers"
Body string json:"body"
}
type Passanger struct {
bson.ObjectId json:"id" bson:"_id"
Title string json:"title" bson:"title"
Image string json:"image" bson:"image"
Price string json:"price" bson:"price"
Rating string json:"rating" bson:"rating"
}
//type Passanger struct {
//ID bson.ObjectId bson:"_id,omitempty"
//Title string
//Image string
//Price string
//Rating string
//}
var (
IsDrop = true
)
type Adapter func(http.Handler) http.Handler
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
for _, adapter := range adapters {
h = adapter(h)
}
return h
}
func main() {
fmt.Println("Starting the application...")
url := "http://"
fmt.Println("URL:>", url)
jsonData := map[string]string{}
jsonValue, _ := json.Marshal(jsonData)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonValue))
req.Header.Set("Content-Type", "application/json")
// req.Header.Set("Authorization", strAuthorization)
client := &http.Client{}
response, err := client.Do(req)
var info map[string]interface{}
var infodata string
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
} else {
data, _ := ioutil.ReadAll(response.Body)
//defer response.Body.Close()
//json.Unmarshal(data, &info)
fmt.Printf("ALTEA Response: %s\n", string(data))
}
fmt.Println("Save Data To Database...")
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
// Drop Database
if IsDrop {
err = session.DB("test").DropDatabase()
if err != nil {
panic(err)
}
}
// Collection Passanger
c := session.DB("flylist").C("passanger")
// Index
index := mgo.Index{
Key: []string{"title", "image", "price", "rating"},
Unique: true,
DropDups: true,
Background: true,
Sparse: true,
}
err = c.EnsureIndex(index)
if err != nil {
panic(err)
}
// Insert Datas
infodata = info["data"].(map[string]interface{})["id"].(string)
//konversi:= []byte(info)
err = c.Insert(&Passanger{Title: string(infodata[0]), Image: string(infodata[1]), Price: string(infodata[2]), Rating: string(infodata[3])})
if err != nil {
panic(err)
}
// Query All
var results []Passanger
err = c.Find(bson.M{"name": "Ale"}).Sort("-timestamp").All(&results)
if err != nil {
panic(err)
}
fmt.Println("Results All: ", results)
}
Please correct my code, thanks alot before
Aren't you supposed to Copy the MongoDB session per request?