Skip to content

Commit e8c083a

Browse files
committed
POC is almost done
1 parent 09c64e6 commit e8c083a

File tree

6 files changed

+304
-78
lines changed

6 files changed

+304
-78
lines changed

api.go

Lines changed: 97 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
/*!
2-
* utils-api-framework
2+
* rest-api-framework
33
* Copyright(c) 2019 Roshan Gade
44
* MIT Licensed
55
*/
66
package rest
77

88
import (
99
"./utils"
10+
"errors"
1011
"fmt"
1112
"net/http"
1213
"regexp"
1314
)
1415

16+
/**
17+
* API - Application
18+
*/
1519
type API struct {
1620
routes []route
1721
interceptors []interceptor
18-
errors []errorHandler
22+
exceptions []exception
23+
unhandled func(ctx *Context)
1924
}
2025

26+
/**
27+
* Route
28+
*/
2129
type route struct {
2230
method string
2331
pattern string
@@ -26,17 +34,25 @@ type route struct {
2634
handle func(ctx *Context)
2735
}
2836

37+
/**
38+
* Request interceptor
39+
*/
2940
type interceptor struct {
3041
handle func(ctx *Context)
3142
}
3243

33-
//TODO: check errors in language specifications
34-
type errorHandler struct {
35-
code string
36-
handle func(ctx *Context)
44+
/**
45+
* Exception Route
46+
*/
47+
type exception struct {
48+
message string
49+
handle func(ctx *Context)
3750
}
3851

39-
func (api *API) handler(method string, pattern string, handle func(ctx *Context)) {
52+
/**
53+
* Common Route
54+
*/
55+
func (api *API) Route(method string, pattern string, handle func(ctx *Context)) {
4056
regex, params, err := utils.Compile(pattern)
4157
if err != nil {
4258
fmt.Println("Error in pattern", err)
@@ -51,79 +67,115 @@ func (api *API) handler(method string, pattern string, handle func(ctx *Context)
5167
})
5268
}
5369

70+
/**
71+
* Required handle for http module
72+
*/
5473
func (api API) ServeHTTP(res http.ResponseWriter, req *http.Request) {
55-
//fmt.Println("-------------------------------------")
56-
//fmt.Println("URI: ", req.RequestURI)
57-
//fmt.Println("Method: ", req.Method)
58-
//fmt.Println("Form: ", req.Form)
59-
//fmt.Println("RawPath: ", req.URL.RawPath)
60-
//fmt.Println("Header: ", req.Header)
61-
//fmt.Println("Path: ", req.URL.Path)
62-
//fmt.Println("RawQuery: ", req.URL.RawQuery)
63-
//fmt.Println("Opaque: ", req.URL.Opaque)
64-
//fmt.Println("-------------------------------------")
74+
6575
urlPath := []byte(req.URL.Path)
6676

6777
ctx := Context{
68-
req: req,
69-
res: res,
78+
Request: req,
79+
Response: res,
7080
}
7181

82+
// STEP 1: initialize context
7283
ctx.init()
84+
defer ctx.destroy()
7385

74-
for _, route := range api.interceptors {
75-
if ctx.err != nil {
76-
break
77-
}
78-
79-
if ctx.end == true {
86+
// STEP 2: execute all interceptors
87+
for _, task := range api.interceptors {
88+
if ctx.end || ctx.err != nil {
8089
break
8190
}
8291

83-
route.handle(&ctx)
92+
task.handle(&ctx)
8493
}
8594

95+
// STEP 3: check routes
8696
for _, route := range api.routes {
87-
if ctx.err != nil {
88-
break
89-
}
90-
91-
if ctx.end == true {
97+
if ctx.end || ctx.err != nil {
9298
break
9399
}
94100

95101
if route.method == req.Method && route.regex.Match(urlPath) {
102+
ctx.found = true
96103
ctx.Params = utils.Exec(route.regex, route.params, urlPath)
97104
route.handle(&ctx)
98105
}
99106
}
100107

101-
//TODO: NOT FOUND, INTERNAL SERVER ERROR, ETC
102-
103-
for _, route := range api.errors {
104-
if ctx.end == true {
108+
// STEP 4: check handled exceptions
109+
for _, exp := range api.exceptions {
110+
if ctx.end || ctx.err == nil {
105111
break
106112
}
107113

108-
if ctx.err != nil && route.code == ctx.err.Error() {
109-
route.handle(&ctx)
114+
if exp.message == ctx.err.Error() {
115+
exp.handle(&ctx)
116+
}
117+
}
118+
119+
// STEP 5: unhandled exceptions
120+
if !ctx.end {
121+
if ctx.err == nil && !ctx.found {
122+
ctx.err = errors.New("URL_NOT_FOUND")
123+
}
124+
125+
if api.unhandled != nil {
126+
api.unhandled(&ctx)
110127
}
111128
}
129+
130+
// STEP 6: system handle
131+
if !ctx.end {
132+
ctx.unhandledException()
133+
}
112134
}
113135

114136
func (api *API) Use(handle func(ctx *Context)) {
115-
api.interceptors = append(api.interceptors, interceptor{handle: handle})
137+
task := interceptor{
138+
handle: handle,
139+
}
140+
api.interceptors = append(api.interceptors, task)
116141
}
117142

118143
func (api *API) GET(pattern string, handle func(ctx *Context)) {
119-
api.handler("GET", pattern, handle)
144+
api.Route("GET", pattern, handle)
120145
}
121146

122-
//TODO: POST, PUT, DELETE, OPTIONS, HEAD, PATCH
147+
func (api *API) POST(pattern string, handle func(ctx *Context)) {
148+
api.Route("POST", pattern, handle)
149+
}
123150

124-
func (api *API) Error(code string, handle func(ctx *Context)) {
125-
api.errors = append(api.errors, errorHandler{
126-
code: code,
127-
handle: handle,
128-
})
151+
func (api *API) PUT(pattern string, handle func(ctx *Context)) {
152+
api.Route("PUT", pattern, handle)
153+
}
154+
155+
func (api *API) DELETE(pattern string, handle func(ctx *Context)) {
156+
api.Route("DELETE", pattern, handle)
157+
}
158+
159+
func (api *API) OPTIONS(pattern string, handle func(ctx *Context)) {
160+
api.Route("OPTIONS", pattern, handle)
161+
}
162+
163+
func (api *API) HEAD(pattern string, handle func(ctx *Context)) {
164+
api.Route("HEAD", pattern, handle)
165+
}
166+
167+
func (api *API) PATCH(pattern string, handle func(ctx *Context)) {
168+
api.Route("PATCH", pattern, handle)
169+
}
170+
171+
func (api *API) Exception(err string, handle func(ctx *Context)) {
172+
exp := exception{
173+
message: err,
174+
handle: handle,
175+
}
176+
api.exceptions = append(api.exceptions, exp)
177+
}
178+
179+
func (api *API) UnhandledException(handle func(ctx *Context)) {
180+
api.unhandled = handle
129181
}

0 commit comments

Comments
 (0)