Skip to content
This repository was archived by the owner on Aug 23, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ func GetAlbums(r *http.Request, enc Encoder, db DB) string {
}
if band != "" || title != "" || yri != 0 {
// At least one filter, use Find()
return Must(enc.Encode(toIface(db.Find(band, title, yri))...))
return Must(enc(toIface(db.Find(band, title, yri))...))
}
// Otherwise, return all albums
return Must(enc.Encode(toIface(db.GetAll())...))
return Must(enc(toIface(db.GetAll())...))
}

// GetAlbum returns the requested album.
Expand All @@ -32,10 +32,10 @@ func GetAlbum(enc Encoder, db DB, parms martini.Params) (int, string) {
al := db.Get(id)
if err != nil || al == nil {
// Invalid id, or does not exist
return http.StatusNotFound, Must(enc.Encode(
return http.StatusNotFound, Must(enc(
NewError(ErrCodeNotExist, fmt.Sprintf("the album with id %s does not exist", parms["id"]))))
}
return http.StatusOK, Must(enc.Encode(al))
return http.StatusOK, Must(enc(al))
}

// AddAlbum creates the posted album.
Expand All @@ -45,12 +45,12 @@ func AddAlbum(w http.ResponseWriter, r *http.Request, enc Encoder, db DB) (int,
switch err {
case ErrAlreadyExists:
// Duplicate
return http.StatusConflict, Must(enc.Encode(
return http.StatusConflict, Must(enc(
NewError(ErrCodeAlreadyExists, fmt.Sprintf("the album '%s' from '%s' already exists", al.Title, al.Band))))
case nil:
// TODO : Location is expected to be an absolute URI, as per the RFC2616
w.Header().Set("Location", fmt.Sprintf("/albums/%d", id))
return http.StatusCreated, Must(enc.Encode(al))
return http.StatusCreated, Must(enc(al))
default:
panic(err)
}
Expand All @@ -61,16 +61,16 @@ func UpdateAlbum(r *http.Request, enc Encoder, db DB, parms martini.Params) (int
al, err := getPutAlbum(r, parms)
if err != nil {
// Invalid id, 404
return http.StatusNotFound, Must(enc.Encode(
return http.StatusNotFound, Must(enc(
NewError(ErrCodeNotExist, fmt.Sprintf("the album with id %s does not exist", parms["id"]))))
}
err = db.Update(al)
switch err {
case ErrAlreadyExists:
return http.StatusConflict, Must(enc.Encode(
return http.StatusConflict, Must(enc(
NewError(ErrCodeAlreadyExists, fmt.Sprintf("the album '%s' from '%s' already exists", al.Title, al.Band))))
case nil:
return http.StatusOK, Must(enc.Encode(al))
return http.StatusOK, Must(enc(al))
default:
panic(err)
}
Expand Down Expand Up @@ -110,7 +110,7 @@ func DeleteAlbum(enc Encoder, db DB, parms martini.Params) (int, string) {
id, err := strconv.Atoi(parms["id"])
al := db.Get(id)
if err != nil || al == nil {
return http.StatusNotFound, Must(enc.Encode(
return http.StatusNotFound, Must(enc(
NewError(ErrCodeNotExist, fmt.Sprintf("the album with id %s does not exist", parms["id"]))))
}
db.Delete(id)
Expand Down
17 changes: 5 additions & 12 deletions encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import (

// An Encoder implements an encoding format of values to be sent as response to
// requests on the API endpoints.
type Encoder interface {
Encode(v ...interface{}) (string, error)
}

type Encoder func(v ...interface{}) (string, error)

// Because `panic`s are caught by martini's Recovery handler, it can be used
// to return server-side errors (500). Some helpful text message should probably
Expand All @@ -23,10 +22,8 @@ func Must(data string, err error) string {
return data
}

type jsonEncoder struct{}

// jsonEncoder is an Encoder that produces JSON-formatted responses.
func (_ jsonEncoder) Encode(v ...interface{}) (string, error) {
var jsonEncoder Encoder = func(v ...interface{}) (string, error) {
var data interface{} = v
if v == nil {
// So that empty results produces `[]` and not `null`
Expand All @@ -38,10 +35,8 @@ func (_ jsonEncoder) Encode(v ...interface{}) (string, error) {
return string(b), err
}

type xmlEncoder struct{}

// xmlEncoder is an Encoder that produces XML-formatted responses.
func (_ xmlEncoder) Encode(v ...interface{}) (string, error) {
var xmlEncoder Encoder = func(v ...interface{}) (string, error) {
var buf bytes.Buffer
if _, err := buf.Write([]byte(xml.Header)); err != nil {
return "", err
Expand All @@ -62,10 +57,8 @@ func (_ xmlEncoder) Encode(v ...interface{}) (string, error) {
return buf.String(), nil
}

type textEncoder struct{}

// textEncoder is an Encoder that produces plain text-formatted responses.
func (_ textEncoder) Encode(v ...interface{}) (string, error) {
var textEncoder Encoder = func(v ...interface{}) (string, error) {
var buf bytes.Buffer
for _, v := range v {
if _, err := fmt.Fprintf(&buf, "%s\n", v); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ func MapEncoder(c martini.Context, w http.ResponseWriter, r *http.Request) {
// Inject the requested encoder
switch ft {
case ".xml":
c.MapTo(xmlEncoder{}, (*Encoder)(nil))
c.Map(xmlEncoder)
w.Header().Set("Content-Type", "application/xml")
case ".text":
c.MapTo(textEncoder{}, (*Encoder)(nil))
c.Map(textEncoder)
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
default:
c.MapTo(jsonEncoder{}, (*Encoder)(nil))
c.Map(jsonEncoder)
w.Header().Set("Content-Type", "application/json")
}
}
Expand Down