forked from rs/rest-layer
/
main.go
124 lines (111 loc) · 3.09 KB
/
main.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// +build go1.7
package main
import (
"context"
"log"
"net"
"net/http"
"net/http/httptest"
"strings"
"github.com/afex/hystrix-go/hystrix"
"github.com/justinas/alice"
"github.com/rs/rest-layer-hystrix"
"github.com/rs/rest-layer-mem"
"github.com/rs/rest-layer/resource"
"github.com/rs/rest-layer/rest"
"github.com/rs/rest-layer/schema"
"github.com/rs/xaccess"
"github.com/rs/xlog"
)
var (
post = schema.Schema{
Fields: schema.Fields{
"id": schema.IDField,
"created": schema.CreatedField,
"updated": schema.UpdatedField,
"title": {},
"body": {},
},
}
)
func main() {
index := resource.NewIndex()
index.Bind("posts", post, restrix.Wrap("posts", mem.NewHandler()), resource.Conf{
AllowedModes: resource.ReadWrite,
})
// Create API HTTP handler for the resource graph
api, err := rest.NewHandler(index)
if err != nil {
log.Fatalf("Invalid API configuration: %s", err)
}
// Setup logger
c := alice.New()
c = c.Append(xlog.NewHandler(xlog.Config{}))
c = c.Append(xaccess.NewHandler())
resource.LoggerLevel = resource.LogLevelDebug
resource.Logger = func(ctx context.Context, level resource.LogLevel, msg string, fields map[string]interface{}) {
xlog.FromContext(ctx).OutputF(xlog.Level(level), 2, msg, fields)
}
// Bind the API under the root path
http.Handle("/", c.Then(api))
// Configure hystrix commands
hystrix.Configure(map[string]hystrix.CommandConfig{
"posts.MultiGet": {
Timeout: 500,
MaxConcurrentRequests: 200,
ErrorPercentThreshold: 25,
},
"posts.Find": {
Timeout: 1000,
MaxConcurrentRequests: 100,
ErrorPercentThreshold: 25,
},
"posts.Insert": {
Timeout: 1000,
MaxConcurrentRequests: 50,
ErrorPercentThreshold: 25,
},
"posts.Update": {
Timeout: 1000,
MaxConcurrentRequests: 50,
ErrorPercentThreshold: 25,
},
"posts.Delete": {
Timeout: 1000,
MaxConcurrentRequests: 10,
ErrorPercentThreshold: 10,
},
"posts.Clear": {
Timeout: 10000,
MaxConcurrentRequests: 5,
ErrorPercentThreshold: 10,
},
})
// Start the metrics stream handler
hystrixStreamHandler := hystrix.NewStreamHandler()
hystrixStreamHandler.Start()
log.Print("Serving Hystrix metrics on http://localhost:8081")
go http.ListenAndServe(net.JoinHostPort("", "8081"), hystrixStreamHandler)
// Inject some fixtures
fixtures := [][]string{
{"POST", "/posts", `{"title": "First Post", "body": "This is my first post"}`},
{"POST", "/posts", `{"title": "Second Post", "body": "This is my second post"}`},
{"POST", "/posts", `{"title": "Third Post", "body": "This is my third post"}`},
}
for _, fixture := range fixtures {
req, err := http.NewRequest(fixture[0], fixture[1], strings.NewReader(fixture[2]))
if err != nil {
log.Fatal(err)
}
w := httptest.NewRecorder()
api.ServeHTTP(w, req)
if w.Code >= 400 {
log.Fatalf("Error returned for `%s %s`: %v", fixture[0], fixture[1], w)
}
}
// Serve it
log.Print("Serving API on http://localhost:8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}