Skip to content

Commit 7108e20

Browse files
authored
Merge pull request #14 from go-rs/develop
Develop
2 parents f9a3e27 + a929da8 commit 7108e20

File tree

10 files changed

+58
-29
lines changed

10 files changed

+58
-29
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,27 @@ fmt.Println("Starting server.")
5959
http.ListenAndServe(":8080", api)
6060
```
6161

62+
63+
## Extend routes
64+
```
65+
var user = rest.Extend("/user", api)
66+
67+
user.Use(func(ctx *rest.Context) {
68+
//User middleware will execute for /user/* routes
69+
})
70+
71+
user.Get("/:uid/profile", func(ctx *rest.Context) {
72+
ctx.JSON(`{"user": "profile"}`)
73+
})
74+
75+
user.Get("/:uid", func(ctx *rest.Context) {
76+
ctx.JSON(ctx.Params)
77+
})
78+
```
79+
80+
###Pending
81+
- Stop execution on timeout/abort
82+
6283
## Documentation
6384
https://godoc.org/github.com/go-rs/rest-api-framework
6485

api.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ func (api *API) UnhandledException(handle Handler) {
153153

154154
// error variables to handle expected errors
155155
var (
156-
ErrCodeNotFound = "URL_NOT_FOUND"
157-
ErrCodeUncaughtException = "UNCAUGHT_EXCEPTION"
156+
ErrCodeNotFound = "URL_NOT_FOUND"
157+
ErrCodeRuntimeError = "RUNTIME_ERROR"
158158
)
159159

160160
// It's required handle for http module.
@@ -175,7 +175,7 @@ func (api *API) ServeHTTP(res http.ResponseWriter, req *http.Request) {
175175
err := recover()
176176
if err != nil {
177177
if !ctx.end {
178-
ctx.code = ErrCodeUncaughtException
178+
ctx.code = ErrCodeRuntimeError
179179
ctx.err = fmt.Errorf("%v", err)
180180
ctx.unhandledException()
181181
}

api_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func TestAPI_Patch(t *testing.T) {
9090
validateRoute("Patch", "PATCH", "/:uid", t)
9191
}
9292

93-
func TestAPI_Exception(t *testing.T) {
93+
func TestAPI_OnError(t *testing.T) {
9494
a.OnError("UID_NOT_FOUND", handle)
9595

9696
flag := true

context.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,16 @@ func (ctx *Context) unhandledException() {
216216

217217
// NOT FOUND handler
218218
if ctx.code == ErrCodeNotFound {
219-
http.NotFound(ctx.Response, ctx.Request)
220-
return
219+
ctx.Status(http.StatusNotFound)
221220
}
222221

223222
if ctx.code != "" || ctx.err != nil {
224-
msg := ctx.code
223+
msg := "Error Code: " + ctx.code
225224
if ctx.err != nil {
226-
msg += "\nError: " + ctx.err.Error()
225+
msg += "\nError Message: " + ctx.err.Error()
227226
}
228227
ctx.SetHeader("Content-Type", "text/plain;charset=UTF-8")
229-
if ctx.status > 400 {
228+
if ctx.status < 400 {
230229
ctx.Status(http.StatusInternalServerError)
231230
}
232231
ctx.Write([]byte(msg))
@@ -238,11 +237,9 @@ func (ctx *Context) recover() {
238237
err := recover()
239238
if err != nil {
240239
//TODO: debugger mode
241-
log.Println("Unhandled Error: ", err)
240+
log.Println("Runtime Error: ", err)
242241
if !ctx.requestSent {
243-
ctx.Response.WriteHeader(http.StatusInternalServerError)
244-
ctx.Response.Header().Set("Content-Type", "text/plain;charset=UTF-8")
245-
_, _ = ctx.Response.Write([]byte("Internal Server Error"))
242+
http.Error(ctx.Response, "Internal Server Error", http.StatusInternalServerError)
246243
}
247244
}
248245
}

examples/server.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"fmt"
5+
"log"
56
"net/http"
67
"strconv"
78
"time"
@@ -32,7 +33,7 @@ func main() {
3233
s := time.Now().UnixNano()
3334
ctx.PreSend(func() {
3435
x := time.Now().UnixNano() - s
35-
ctx.SetHeader("X-Runtime", strconv.FormatInt(x/int64(time.Millisecond), 10))
36+
ctx.SetHeader("X-Runtime", strconv.FormatInt(x/int64(time.Microsecond), 10))
3637
})
3738
})
3839

@@ -43,6 +44,7 @@ func main() {
4344

4445
api.Get("/foo", func(ctx *rest.Context) {
4546
ctx.Throw("UNAUTHORIZED")
47+
// can also use ctx.ThrowWithError("SERVER_ERROR", error)
4648
})
4749

4850
// error handler
@@ -52,7 +54,15 @@ func main() {
5254

5355
fmt.Println("Starting server.")
5456

55-
err := http.ListenAndServe(":8080", api)
57+
tout := http.TimeoutHandler(api, 100*time.Millisecond, "timeout")
58+
59+
server := http.Server{
60+
Addr: ":8080",
61+
Handler: tout,
62+
}
63+
64+
if err := server.ListenAndServe(); err != nil {
65+
log.Fatalf("could not start server, %v", err)
66+
}
5667

57-
fmt.Println(err)
5868
}

examples/user/user.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ import (
66

77
func Load(api *rest.API) {
88

9-
var user rest.Namespace
10-
11-
user.Set("/user", api)
9+
var user = rest.Extend("/user", api)
1210

1311
user.Use(func(ctx *rest.Context) {
1412
println("User middleware > /user/*")

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/go-rs/rest-api-framework
22

3-
go 1.12
3+
go 1.13

namespace.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
package rest
66

77
import (
8-
"github.com/go-rs/rest-api-framework/utils"
98
"net/http"
9+
10+
"github.com/go-rs/rest-api-framework/utils"
1011
)
1112

1213
// Namespace is used to extend routes with a specific prefix
@@ -16,10 +17,12 @@ type Namespace struct {
1617
}
1718

1819
// Set method is used to set prefix with API
19-
func (n *Namespace) Set(prefix string, api *API) {
20+
func Extend(prefix string, api *API) *Namespace {
2021
prefix = utils.TrimSuffix(prefix, "/")
21-
n.prefix = prefix
22-
n.api = api
22+
return &Namespace{
23+
prefix: prefix,
24+
api: api,
25+
}
2326
}
2427

2528
// Use method is used to set interceptors/middlewares for all requests,

namespace_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import (
99
)
1010

1111
var api API
12-
var ns Namespace
12+
var ns *Namespace
1313
var handle Handler
1414

15-
func TestNamespace_Set(t *testing.T) {
16-
ns.Set("/test", &api)
15+
func TestExtend(t *testing.T) {
16+
ns = Extend("/test", &api)
1717

1818
if ns.prefix != "/test" {
1919
t.Error("Prefix is not set.")
@@ -88,7 +88,7 @@ func TestNamespace_Patch(t *testing.T) {
8888
validateNsRoute("Patch", "PATCH", "/test/:uid", t)
8989
}
9090

91-
func TestNamespace_Exception(t *testing.T) {
91+
func TestNamespace_OnError(t *testing.T) {
9292
ns.OnError("UID_NOT_FOUND", handle)
9393

9494
flag := true

render/text_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func TestText_Write(t *testing.T) {
2020
t.Error("Render text is not valid")
2121
}
2222

23-
if w.Header().Get("Content-Type") != "text/plain" {
23+
if w.Header().Get("Content-Type") != "text/plain;charset=UTF-8" {
2424
t.Error("Content-Type Header is not set.")
2525
}
2626
}

0 commit comments

Comments
 (0)