-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.go
101 lines (85 loc) · 2.34 KB
/
api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package main
import (
"compress/gzip"
"encoding/json"
"net/http"
"log"
"strings"
"github.com/julienschmidt/httprouter"
)
// GoBGP http API
//
// This API provides some read-only endpoints
// for querying GoBGP via a HTTP interface.
//
// This is intended for use in a looking glass integration
// context.
//
// Endpoints:
//
// Neighbours
// List /v1/neighbours
// Show /v1/neighbours/:id
//
// Routes
// Show Id /v1/neighbours/:id/routes
//
type ErrorResponse struct {
Error string `json:"error"`
}
type ApiResponse struct {
Meta map[string]interface{} `json:"meta"`
Result ApiResult `json:"result"`
}
type ApiResult interface{}
type apiEndpoint func(*http.Request, httprouter.Params) (ApiResult, error)
// Wrap handler for access controll, throtteling and compression
func endpoint(wrapped apiEndpoint) httprouter.Handle {
return func(res http.ResponseWriter,
req *http.Request,
params httprouter.Params) {
// Get result from handler
result, err := wrapped(req, params)
if err != nil {
result = ErrorResponse{
Error: err.Error(),
}
payload, _ := json.Marshal(result)
http.Error(res, string(payload), http.StatusInternalServerError)
return
}
// Wrap into response
response := ApiResponse{
Result: result,
}
// Encode json
payload, err := json.Marshal(response)
if err != nil {
msg := "Could not encode result as json"
http.Error(res, msg, http.StatusInternalServerError)
log.Println(err)
log.Println("This is most likely due to an older version of go.")
log.Println("Consider upgrading to golang > 1.8")
return
}
// Set response header
res.Header().Set("Content-Type", "application/json")
// Check if compression is supported
if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
// Compress response
res.Header().Set("Content-Encoding", "gzip")
gz := gzip.NewWriter(res)
defer gz.Close()
gz.Write(payload)
} else {
res.Write(payload) // Fall back to uncompressed response
}
}
}
// Register api endpoints
func apiRegisterEndpoints(router *httprouter.Router) {
router.GET("/v1/status", endpoint(apiShowStatus))
router.GET("/v1/neighbours", endpoint(apiListNeighbours))
router.GET("/v1/neighbours/:id", endpoint(apiShowNeighbour))
router.GET("/v1/neighbours/:id/routes", endpoint(apiShowRoutes))
}