Skip to content

Commit 34f9e1e

Browse files
committed
Added namespace support
1 parent e8c083a commit 34f9e1e

File tree

6 files changed

+150
-54
lines changed

6 files changed

+150
-54
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Roshan Gade
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

api.go

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@
66
package rest
77

88
import (
9-
"./utils"
109
"errors"
1110
"fmt"
11+
"github.com/go-rs/rest-api-framework/utils"
1212
"net/http"
1313
"regexp"
1414
)
1515

16+
type Handler func(ctx *Context)
17+
1618
/**
1719
* API - Application
1820
*/
1921
type API struct {
22+
prefix string
2023
routes []route
2124
interceptors []interceptor
2225
exceptions []exception
23-
unhandled func(ctx *Context)
26+
unhandled Handler
2427
}
2528

2629
/**
@@ -31,28 +34,28 @@ type route struct {
3134
pattern string
3235
regex *regexp.Regexp
3336
params []string
34-
handle func(ctx *Context)
37+
handle Handler
3538
}
3639

3740
/**
3841
* Request interceptor
3942
*/
4043
type interceptor struct {
41-
handle func(ctx *Context)
44+
handle Handler
4245
}
4346

4447
/**
4548
* Exception Route
4649
*/
4750
type exception struct {
4851
message string
49-
handle func(ctx *Context)
52+
handle Handler
5053
}
5154

5255
/**
5356
* Common Route
5457
*/
55-
func (api *API) Route(method string, pattern string, handle func(ctx *Context)) {
58+
func (api *API) Route(method string, pattern string, handle Handler) {
5659
regex, params, err := utils.Compile(pattern)
5760
if err != nil {
5861
fmt.Println("Error in pattern", err)
@@ -98,8 +101,8 @@ func (api API) ServeHTTP(res http.ResponseWriter, req *http.Request) {
98101
break
99102
}
100103

101-
if route.method == req.Method && route.regex.Match(urlPath) {
102-
ctx.found = true
104+
if (route.method == "" || route.method == req.Method) && route.regex.Match(urlPath) {
105+
ctx.found = route.method != "" //?
103106
ctx.Params = utils.Exec(route.regex, route.params, urlPath)
104107
route.handle(&ctx)
105108
}
@@ -133,49 +136,53 @@ func (api API) ServeHTTP(res http.ResponseWriter, req *http.Request) {
133136
}
134137
}
135138

136-
func (api *API) Use(handle func(ctx *Context)) {
139+
func (api *API) Use(handle Handler) {
137140
task := interceptor{
138141
handle: handle,
139142
}
140143
api.interceptors = append(api.interceptors, task)
141144
}
142145

143-
func (api *API) GET(pattern string, handle func(ctx *Context)) {
146+
func (api *API) All(pattern string, handle Handler) {
147+
api.Route("", pattern, handle)
148+
}
149+
150+
func (api *API) Get(pattern string, handle Handler) {
144151
api.Route("GET", pattern, handle)
145152
}
146153

147-
func (api *API) POST(pattern string, handle func(ctx *Context)) {
154+
func (api *API) Post(pattern string, handle Handler) {
148155
api.Route("POST", pattern, handle)
149156
}
150157

151-
func (api *API) PUT(pattern string, handle func(ctx *Context)) {
158+
func (api *API) Put(pattern string, handle Handler) {
152159
api.Route("PUT", pattern, handle)
153160
}
154161

155-
func (api *API) DELETE(pattern string, handle func(ctx *Context)) {
162+
func (api *API) Delete(pattern string, handle Handler) {
156163
api.Route("DELETE", pattern, handle)
157164
}
158165

159-
func (api *API) OPTIONS(pattern string, handle func(ctx *Context)) {
166+
func (api *API) Options(pattern string, handle Handler) {
160167
api.Route("OPTIONS", pattern, handle)
161168
}
162169

163-
func (api *API) HEAD(pattern string, handle func(ctx *Context)) {
170+
func (api *API) Head(pattern string, handle Handler) {
164171
api.Route("HEAD", pattern, handle)
165172
}
166173

167-
func (api *API) PATCH(pattern string, handle func(ctx *Context)) {
174+
func (api *API) Patch(pattern string, handle Handler) {
168175
api.Route("PATCH", pattern, handle)
169176
}
170177

171-
func (api *API) Exception(err string, handle func(ctx *Context)) {
178+
func (api *API) Exception(err string, handle Handler) {
172179
exp := exception{
173180
message: err,
174181
handle: handle,
175182
}
176183
api.exceptions = append(api.exceptions, exp)
177184
}
178185

179-
func (api *API) UnhandledException(handle func(ctx *Context)) {
186+
func (api *API) UnhandledException(handle Handler) {
180187
api.unhandled = handle
181188
}

context.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
package rest
77

88
import (
9-
"./render"
9+
"github.com/go-rs/rest-api-framework/render"
1010
"net/http"
1111
)
1212

@@ -150,10 +150,13 @@ func (ctx *Context) send(data []byte, err error) {
150150
* Unhandled Exception
151151
*/
152152
func (ctx *Context) unhandledException() {
153-
err := ctx.GetError().Error()
154-
ctx.Status(500)
155-
if err == "URL_NOT_FOUND" {
156-
ctx.Status(404)
153+
err := ctx.GetError()
154+
if err != nil {
155+
msg := err.Error()
156+
ctx.Status(500)
157+
if msg == "URL_NOT_FOUND" {
158+
ctx.Status(404)
159+
}
160+
ctx.Write([]byte(msg))
157161
}
158-
ctx.Write([]byte(err))
159162
}

examples/server.go

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,34 @@ import (
44
".."
55
"errors"
66
"fmt"
7+
"github.com/go-rs/rest-api-framework/examples/user"
78
"net/http"
89
)
910

1011
func main() {
1112
var api rest.API
1213

14+
user.APIs(&api)
15+
1316
// request interceptor / middleware
14-
// method-override
1517
// body-parser : json, raw, form-data, etc
1618
// security
1719
api.Use(func(ctx *rest.Context) {
1820
ctx.Set("authtoken", "roshangade")
1921
})
2022

2123
// routes
22-
api.GET("/", func(ctx *rest.Context) {
23-
ctx.Text("Hello World!")
24+
api.Get("/", func(ctx *rest.Context) {
25+
ctx.JSON(`{"message": "Hello World!"}`)
2426
})
2527

26-
api.GET("/foo", func(ctx *rest.Context) {
28+
api.Get("/foo", func(ctx *rest.Context) {
2729
ctx.Throw(errors.New("UNAUTHORIZED"))
2830
})
2931

30-
api.GET("/strut", func(ctx *rest.Context) {
31-
type user struct {
32-
Name string
33-
}
34-
35-
u := user{
36-
Name: "roshan",
37-
}
38-
39-
ctx.JSON(u)
40-
})
41-
42-
api.GET("/json", func(ctx *rest.Context) {
43-
ctx.JSON(`{"test": "JSON Response"}`)
44-
})
45-
46-
api.GET("/:bar", func(ctx *rest.Context) {
47-
fmt.Println("authtoken", ctx.Get("authtoken"))
48-
ctx.JSON(ctx.Params)
49-
})
50-
5132
// error handler
5233
api.Exception("UNAUTHORIZED", func(ctx *rest.Context) {
53-
ctx.Status(401).Text("You are unauthorized")
54-
})
55-
56-
api.UnhandledException(func(ctx *rest.Context) {
57-
fmt.Println("---> ", ctx.GetError())
34+
ctx.Status(401).JSON(`{"message": "You are unauthorized"}`)
5835
})
5936

6037
fmt.Println("Starting server.")

examples/user/user.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package user
2+
3+
import (
4+
"../.."
5+
)
6+
7+
func APIs(api *rest.API) {
8+
9+
var user rest.Namespace
10+
11+
user.Set("/user", api)
12+
13+
user.Use(func(ctx *rest.Context) {
14+
println("User middleware > /user/*")
15+
})
16+
17+
user.Get("/:uid/profile", func(ctx *rest.Context) {
18+
ctx.JSON(`{"user": "profile"}`)
19+
})
20+
21+
user.Get("/:uid", func(ctx *rest.Context) {
22+
ctx.JSON(ctx.Params)
23+
})
24+
}

namespace.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*!
2+
* rest-api-framework
3+
* Copyright(c) 2019 Roshan Gade
4+
* MIT Licensed
5+
*/
6+
package rest
7+
8+
/**
9+
* Namespace - Application
10+
*/
11+
type Namespace struct {
12+
prefix string
13+
api *API
14+
}
15+
16+
//TODO: error handling on unset api
17+
func (n *Namespace) Set(prefix string, api *API) {
18+
n.prefix = prefix
19+
n.api = api
20+
}
21+
22+
func (n *Namespace) Use(handle Handler) {
23+
n.api.Route("", n.prefix+"/*", handle)
24+
}
25+
26+
func (n *Namespace) All(pattern string, handle Handler) {
27+
n.api.Route("", n.prefix+pattern, handle)
28+
}
29+
30+
func (n *Namespace) Get(pattern string, handle Handler) {
31+
n.api.Route("GET", n.prefix+pattern, handle)
32+
}
33+
34+
func (n *Namespace) Post(pattern string, handle Handler) {
35+
n.api.Route("POST", n.prefix+pattern, handle)
36+
}
37+
38+
func (n *Namespace) Put(pattern string, handle Handler) {
39+
n.api.Route("PUT", n.prefix+pattern, handle)
40+
}
41+
42+
func (n *Namespace) Delete(pattern string, handle Handler) {
43+
n.api.Route("DELETE", n.prefix+pattern, handle)
44+
}
45+
46+
func (n *Namespace) Options(pattern string, handle Handler) {
47+
n.api.Route("OPTIONS", n.prefix+pattern, handle)
48+
}
49+
50+
func (n *Namespace) Head(pattern string, handle Handler) {
51+
n.api.Route("HEAD", n.prefix+pattern, handle)
52+
}
53+
54+
func (n *Namespace) Patch(pattern string, handle Handler) {
55+
n.api.Route("PATCH", n.prefix+pattern, handle)
56+
}
57+
58+
func (n *Namespace) Exception(err string, handle Handler) {
59+
exp := exception{
60+
message: err,
61+
handle: handle,
62+
}
63+
n.api.exceptions = append(n.api.exceptions, exp)
64+
}

0 commit comments

Comments
 (0)