11// go-rs/rest-api-framework
2- // Copyright(c) 2019 Roshan Gade. All rights reserved.
2+ // Copyright(c) 2019 Roshan Gade. All rights reserved.
33// MIT Licensed
44
55package rest
66
77import (
8+ "log"
89 "net/http"
910 "net/url"
1011
1112 "github.com/go-rs/rest-api-framework/render"
1213)
1314
15+ // Task, which is used to perform a specific job,
16+ // just before request completion or after request completion
1417type Task func ()
1518
16- /**
17- * Context
18- */
19+ // Context, which initializes at every request with pre-declared variables
20+ // such as Request, Response, Query, Body, Params etc.
1921type Context struct {
20- Request * http.Request
21- Response http.ResponseWriter
22- Query url.Values
23- Body interface {}
24- Params map [string ]string
22+ // available to users
23+ Request * http.Request
24+ Response http.ResponseWriter
25+ Query url.Values
26+ Body interface {}
27+ Params map [string ]string
28+
29+ // for internal use
2530 headers map [string ]string
2631 data map [string ]interface {}
2732 err error
@@ -35,150 +40,134 @@ type Context struct {
3540 postSendTasks []Task
3641}
3742
38- /**
39- * Initialization of context on every request
40- */
43+ // Initialization of context data on every request
4144func (ctx * Context ) init () {
4245 ctx .headers = make (map [string ]string )
4346 ctx .data = make (map [string ]interface {})
4447 ctx .preSendTasks = make ([]Task , 0 )
4548 ctx .postSendTasks = make ([]Task , 0 )
4649 ctx .status = 200
47- ctx .found = false
48- ctx .end = false
4950}
5051
51- /**
52- * Destroy context once request end
53- */
52+ // Destroy context data once request end
5453func (ctx * Context ) destroy () {
5554 ctx .Request = nil
5655 ctx .Response = nil
56+ ctx .Query = nil
57+ ctx .Body = nil
5758 ctx .Params = nil
59+ ctx .headers = nil
5860 ctx .data = nil
5961 ctx .err = nil
6062 ctx .status = 0
6163 ctx .found = false
6264 ctx .end = false
65+ ctx .requestSent = false
66+ ctx .preTasksCalled = false
67+ ctx .postTasksCalled = false
68+ ctx .preSendTasks = nil
69+ ctx .postSendTasks = nil
6370}
6471
65- /**
66- * Set request data in context
67- */
72+ // Set data
6873func (ctx * Context ) Set (key string , val interface {}) {
6974 ctx .data [key ] = val
7075}
7176
72- /**
73- * Get request data from context
74- */
77+ // Get data
7578func (ctx * Context ) Get (key string ) (val interface {}, exists bool ) {
76- val = ctx .data [key ]
77- exists = val != nil
79+ val , exists = ctx .data [key ]
7880 return
7981}
8082
81- /**
82- * Set Status
83- */
83+ // Delete data
84+ func (ctx * Context ) Delete (key string , val interface {}) {
85+ delete (ctx .data , key )
86+ }
87+
88+ // Set response status
8489func (ctx * Context ) Status (code int ) * Context {
8590 ctx .status = code
8691 return ctx
8792}
8893
89- /**
90- * Set Header
91- */
94+ // Set response header
9295func (ctx * Context ) SetHeader (key string , val string ) * Context {
9396 ctx .headers [key ] = val
9497 return ctx
9598}
9699
97- /**
98- * Throw error
99- */
100+ // Caught error in context on throw
100101func (ctx * Context ) Throw (err error ) {
101102 ctx .err = err
102103}
103104
104- /**
105- * Get error
106- */
105+ // Get error if any
107106func (ctx * Context ) GetError () error {
108107 return ctx .err
109108}
110109
111- /**
112- * End
113- */
110+ // Marked the request is ended
114111func (ctx * Context ) End () {
115112 ctx .end = true
116113}
117114
118- /**
119- * Write Bytes
120- */
115+ // Send response in bytes
121116func (ctx * Context ) Write (data []byte ) {
122117 ctx .send (data , nil )
123118}
124119
125- /**
126- * Write JSON
127- */
120+ // Send JSON data in response
128121func (ctx * Context ) JSON (data interface {}) {
129122 json := render.JSON {
130123 Body : data ,
131124 }
132- body , err := json .Write (ctx .Response )
125+ body , err := json .ToBytes (ctx .Response )
133126 ctx .send (body , err )
134127}
135128
136- /**
137- * Write Text
138- */
129+ // Send text in response
139130func (ctx * Context ) Text (data string ) {
140131 txt := render.Text {
141132 Body : data ,
142133 }
143- body , err := txt .Write (ctx .Response )
134+ body , err := txt .ToBytes (ctx .Response )
144135 ctx .send (body , err )
145136}
146137
147- /**
148- *
149- */
138+ // Register pre-send hook
150139func (ctx * Context ) PreSend (task Task ) {
151140 ctx .preSendTasks = append (ctx .preSendTasks , task )
152141}
153142
154- /**
155- *
156- */
143+ // Register pre-post hook
157144func (ctx * Context ) PostSend (task Task ) {
158145 ctx .postSendTasks = append (ctx .postSendTasks , task )
159146}
160147
161148//////////////////////////////////////////////////
162- /**
163- * Send data
164- */
149+ // Send data, which uses bytes or error if any
150+ // Also, it calls pre-send and post-send registered hooks
165151func (ctx * Context ) send (data []byte , err error ) {
166152 if ctx .end {
167153 return
168154 }
169155
170156 if err != nil {
171157 ctx .err = err
158+ ctx .unhandledException ()
172159 return
173160 }
174161
162+ // execute pre-send hooks
175163 if ! ctx .preTasksCalled {
176164 ctx .preTasksCalled = true
177165 for _ , task := range ctx .preSendTasks {
178166 task ()
179167 }
180168 }
181169
170+ // write data
182171 if ! ctx .requestSent {
183172 ctx .requestSent = true
184173
@@ -191,11 +180,12 @@ func (ctx *Context) send(data []byte, err error) {
191180 _ , err = ctx .Response .Write (data )
192181
193182 if err != nil {
194- ctx . err = err
195- return
183+ //TODO: debugger mode
184+ log . Println ( "Response Error: " , err )
196185 }
197186 }
198187
188+ // execute post-send hooks
199189 if ! ctx .postTasksCalled {
200190 ctx .postTasksCalled = true
201191 for _ , task := range ctx .postSendTasks {
@@ -206,13 +196,13 @@ func (ctx *Context) send(data []byte, err error) {
206196 ctx .End ()
207197}
208198
209- /**
210- * Unhandled Exception
211- */
199+ // Unhandled Exception
212200func (ctx * Context ) unhandledException () {
213201 defer func () {
214202 err := recover ()
215203 if err != nil {
204+ //TODO: debugger mode
205+ log .Println ("Unhandled Error: " , err )
216206 if ! ctx .requestSent {
217207 ctx .Response .WriteHeader (http .StatusInternalServerError )
218208 ctx .Response .Header ().Set ("Content-Type" , "text/plain;charset=UTF-8" )
0 commit comments