Skip to content

Commit ff0bbd6

Browse files
committed
Add link headers
1 parent 59601d6 commit ff0bbd6

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

api.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package main
22

33
import (
4+
"strconv"
45
"encoding/json"
56
"flag"
67
"fmt"
78
"github.com/codegangsta/martini"
89
"github.com/codegangsta/martini-contrib/gzip"
910
"log"
1011
"net/http"
12+
"net/url"
1113
"os"
1214
"strings"
1315
)
@@ -105,7 +107,25 @@ func JSON(code int, val interface{}) (int, []byte) {
105107
return code, blob
106108
}
107109

108-
func GetCards(db *Database, req *http.Request) (int, []byte) {
110+
func LinkHeader(scheme, host string, u *url.URL, q Query) string {
111+
if q.Page == 0 {
112+
qstring := u.Query()
113+
qstring.Set("page", "1")
114+
return fmt.Sprintf("<%s://%s%s?%s>; rel=\"next\"", scheme, host, u.Path, qstring.Encode())
115+
} else {
116+
qstring := u.Query()
117+
118+
qstring.Set("page", strconv.Itoa(q.Page-1))
119+
prev := fmt.Sprintf("<%s://%s%s?%s>; rel=\"prev\"", scheme, host, u.Path, qstring.Encode())
120+
121+
qstring.Set("page", strconv.Itoa(q.Page+1))
122+
next := fmt.Sprintf("<%s://%s%s?%s>; rel=\"next\"", scheme, host, u.Path, qstring.Encode())
123+
124+
return prev + ", " + next
125+
}
126+
}
127+
128+
func GetCards(db *Database, req *http.Request, w http.ResponseWriter) (int, []byte) {
109129
q, err := NewQuery(req)
110130

111131
if err != nil {
@@ -120,6 +140,8 @@ func GetCards(db *Database, req *http.Request) (int, []byte) {
120140
return JSON(http.StatusNotFound, "")
121141
}
122142

143+
w.Header().Set("Link", LinkHeader("http", GetHostname(), req.URL, q))
144+
123145
return JSON(http.StatusOK, cards)
124146
}
125147

@@ -206,7 +228,7 @@ func main() {
206228
m.Use(func(c martini.Context, w http.ResponseWriter) {
207229
w.Header().Set("Content-Type", "application/json; charset=utf-8")
208230
w.Header().Set("Cache-Control", "public,max-age=3600")
209-
w.Header().Set("License", "Card names and text are all copyright Wizards of the Coast. This website is not affiliated with Wizards of the Coast in any way.")
231+
w.Header().Set("License", "Card names and text are copyright Wizards of the Coast. This API is not affiliated with Wizards of the Coast in any way.")
210232
})
211233

212234
r := martini.NewRouter()
@@ -217,8 +239,8 @@ func main() {
217239
r.Get("/mtg/sets", GetSets)
218240
r.Get("/mtg/sets/:id", GetSet)
219241

220-
//They can just download the mtgjson dump
221-
//r.Get("/mtg/editions", GetEditions)
242+
//They can just download the mtgjson dump
243+
//r.Get("/mtg/editions", GetEditions)
222244

223245
m.Action(r.Handle)
224246
m.Map(&db)

api_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"net/url"
5+
"testing"
6+
)
7+
8+
func TestLinkHeader(t *testing.T) {
9+
url, _ := url.Parse("/cards?foo=bar")
10+
header := LinkHeader("http", "localhost:3000", url, Query{Page: 0})
11+
expected := "<http://localhost:3000/cards?foo=bar&page=1>; rel=\"next\""
12+
13+
if header != expected {
14+
t.Errorf("Expected %s not %s", expected, header)
15+
}
16+
17+
url, _ = url.Parse("/cards?foo=bar&page=1")
18+
header = LinkHeader("http", "localhost:3000", url, Query{Page: 1})
19+
expected = "<http://localhost:3000/cards?foo=bar&page=0>; rel=\"prev\", <http://localhost:3000/cards?foo=bar&page=2>; rel=\"next\""
20+
21+
if header != expected {
22+
t.Errorf("Expected %s not %s", expected, header)
23+
}
24+
25+
}

database.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ func NewQuery(req *http.Request) (Query, error) {
143143
return q, err
144144
}
145145

146-
if page < 0 {
147-
return q, fmt.Errorf("Page parameter must be >= 0")
148-
}
146+
if page < 0 {
147+
return q, fmt.Errorf("Page parameter must be >= 0")
148+
}
149149

150150
q.Page = page
151151

0 commit comments

Comments
 (0)