Skip to content

Instantly share code, notes, and snippets.

@up1
Last active October 7, 2015 13:42
Show Gist options
  • Select an option

  • Save up1/ee3f3b3a7f80186c6866 to your computer and use it in GitHub Desktop.

Select an option

Save up1/ee3f3b3a7f80186c6866 to your computer and use it in GitHub Desktop.
GO :: REST API + JSON
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"strings"
)
func main() {
const jsonStream = `
{"ID": 1, "Title": "title 1", "Done": false}
{"ID": 2, "Title": "title 2", "Done": false}
`
type Task struct {
ID int64
Title string
Done bool
}
dec := json.NewDecoder(strings.NewReader(jsonStream))
for {
var task Task
if err := dec.Decode(&task); err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
fmt.Printf("%d: %s : %v\n", task.ID, task.Title, task.Done)
}
}
package main
import (
"encoding/json"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", addHandler)
http.ListenAndServe(":8080", nil)
}
func addHandler(w http.ResponseWriter, r *http.Request) {
type Task struct {
ID int64
Title string
Done bool
}
var task Task
if err := json.NewDecoder(r.Body).Decode(&task); err != nil {
http.Error(w, "bad request", http.StatusBadRequest)
return
}
var resultTask Task
resultTask.ID = task.ID
resultTask.Title = task.Title
resultTask.Done = task.Done
if err := json.NewEncoder(w).Encode(resultTask); err != nil {
log.Println(err)
http.Error(w, "oops", http.StatusInternalServerError)
}
}
if r.Method != "POST" {
http.Error(w, r.Method+" not allowed", http.StatusMethodNotAllowed)
return
}
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", addHandler)
http.ListenAndServe(":8080", nil)
}
func addHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("Hello World")
}
package main
import (
"encoding/json"
"net/http"
"log"
"github.com/gorilla/mux"
"github.com/up1/my_todo/task"
)
var tasks = task.NewTaskManager()
const PathPrefix = "/task/"
func RegisterHandlers() {
route := mux.NewRouter()
route.HandleFunc(PathPrefix, errorHandler(ListTasks)).Methods("GET")
route.HandleFunc(PathPrefix, errorHandler(NewTask)).Methods("POST")
http.Handle(PathPrefix, route)
}
type badRequest struct{ error }
type notFound struct{ error }
func errorHandler(f func(w http.ResponseWriter, r *http.Request) error) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
err := f(w, r)
if err == nil {
return
}
switch err.(type) {
case badRequest:
http.Error(w, err.Error(), http.StatusBadRequest)
case notFound:
http.Error(w, "task not found", http.StatusNotFound)
default:
log.Println(err)
http.Error(w, "oops", http.StatusInternalServerError)
}
}
}
func ListTasks(w http.ResponseWriter, r *http.Request) error {
res := struct{ Tasks []*task.Task }{tasks.GetAll()}
return json.NewEncoder(w).Encode(res)
}
func NewTask(w http.ResponseWriter, r *http.Request) error {
req := struct{ Title string }{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return badRequest{err}
}
t, err := task.NewTask(req.Title)
if err != nil {
return badRequest{err}
}
return tasks.Save(t)
}
func main() {
RegisterHandlers()
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment