@@ -12,7 +12,7 @@ import (
12
12
"golang.org/x/exp/constraints"
13
13
)
14
14
15
- // Handle handles a generic response and error from a service call and sends a JSON response to the context .
15
+ // Handle handles a generic response and error from a service call and sends a JSON response to the client .
16
16
// It returns a boolean value indicating whether the handle was successful or not.
17
17
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
18
18
func Handle (ctx * context.Context , resp interface {}, err error ) bool {
@@ -161,7 +161,7 @@ func bindResponse[T, R any, F ResponseFunc[T, R]](ctx *context.Context, fn F, fn
161
161
return resp , ! HandleError (ctx , err )
162
162
}
163
163
164
- // OK handles a generic response and error from a service call and sends a JSON response to the context .
164
+ // OK handles a generic response and error from a service call and sends a JSON response to the client .
165
165
// It returns a boolean value indicating whether the handle was successful or not.
166
166
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
167
167
// It sets the status code to 200 (OK) and sends any response as a JSON payload.
@@ -176,6 +176,88 @@ func OK[T, R any, F ResponseFunc[T, R]](ctx *context.Context, fn F, fnInput ...T
176
176
return Handle (ctx , resp , nil )
177
177
}
178
178
179
+ // HandlerInputFunc is a function which takes a context and returns a generic type T.
180
+ // It is used to call a service function with a generic type T.
181
+ // It is used for functions which do not bind a request payload.
182
+ // It is used for XHandler functions.
183
+ // Developers can design their own HandlerInputFunc functions and use them with the XHandler functions.
184
+ // To make a value required, stop the context execution through the context.StopExecution function and fire an error
185
+ // or just use one of the [InvalidArgument].X methods.
186
+ //
187
+ // See PathParam, Query and Value package-level helpers too.
188
+ type HandlerInputFunc [T any ] interface {
189
+ func (ctx * context.Context ) T
190
+ }
191
+
192
+ // GetRequestInputs returns a slice of generic type T from a slice of HandlerInputFunc[T].
193
+ // It is exported so end-developers can use it to get the inputs from custom HandlerInputFunc[T] functions.
194
+ func GetRequestInputs [T any , I HandlerInputFunc [T ]](ctx * context.Context , fnInputFunc []I ) ([]T , bool ) {
195
+ inputs := make ([]T , 0 , len (fnInputFunc ))
196
+ for _ , callIn := range fnInputFunc {
197
+ if callIn == nil {
198
+ continue
199
+ }
200
+
201
+ input := callIn (ctx )
202
+ if ctx .IsStopped () { // if the input is required and it's not provided, then the context is stopped.
203
+ return nil , false
204
+ }
205
+ inputs = append (inputs , input )
206
+ }
207
+
208
+ return inputs , true
209
+ }
210
+
211
+ // PathParam returns a HandlerInputFunc which reads a path parameter from the context and returns it as a generic type T.
212
+ // It is used for XHandler functions.
213
+ func PathParam [T any , I HandlerInputFunc [T ]](paramName string ) I {
214
+ return func (ctx * context.Context ) T {
215
+ paramValue := ctx .Params ().Store .Get (paramName )
216
+ if paramValue == nil {
217
+ var t T
218
+ return t
219
+ }
220
+
221
+ return paramValue .(T )
222
+ }
223
+ }
224
+
225
+ // Value returns a HandlerInputFunc which returns a generic type T.
226
+ // It is used for XHandler functions.
227
+ func Value [T any , I HandlerInputFunc [T ]](value T ) I {
228
+ return func (ctx * context.Context ) T {
229
+ return value
230
+ }
231
+ }
232
+
233
+ // Query returns a HandlerInputFunc which reads a URL query from the context and returns it as a generic type T.
234
+ // It is used for XHandler functions.
235
+ func Query [T any , I HandlerInputFunc [T ]]() I {
236
+ return func (ctx * context.Context ) T {
237
+ value , ok := ReadQuery [T ](ctx )
238
+ if ! ok {
239
+ var t T
240
+ return t
241
+ }
242
+
243
+ return value
244
+ }
245
+ }
246
+
247
+ // Handler handles a generic response and error from a service call and sends a JSON response to the client with status code of 200.
248
+ //
249
+ // See OK package-level function for more.
250
+ func Handler [T , R any , F ResponseFunc [T , R ], I HandlerInputFunc [T ]](fn F , fnInput ... I ) context.Handler {
251
+ return func (ctx * context.Context ) {
252
+ inputs , ok := GetRequestInputs (ctx , fnInput )
253
+ if ! ok {
254
+ return
255
+ }
256
+
257
+ OK (ctx , fn , inputs ... )
258
+ }
259
+ }
260
+
179
261
// ListResponseFunc is a function which takes a context,
180
262
// a pagination.ListOptions and a generic type T and returns a slice []R, total count of the items and an error.
181
263
//
@@ -209,6 +291,20 @@ func List[T, R any, C constraints.Integer | constraints.Float, F ListResponseFun
209
291
return Handle (ctx , resp , nil )
210
292
}
211
293
294
+ // ListHandler handles a generic response and error from a service paginated call and sends a JSON response to the client.
295
+ //
296
+ // See List package-level function for more.
297
+ func ListHandler [T , R any , C constraints.Integer | constraints.Float , F ListResponseFunc [T , R , C ], I HandlerInputFunc [T ]](fn F , fnInput ... I ) context.Handler {
298
+ return func (ctx * context.Context ) {
299
+ inputs , ok := GetRequestInputs (ctx , fnInput )
300
+ if ! ok {
301
+ return
302
+ }
303
+
304
+ List (ctx , fn , inputs ... )
305
+ }
306
+ }
307
+
212
308
// Create handles a create operation and sends a JSON response with the created resource to the client.
213
309
// It returns a boolean value indicating whether the handle was successful or not.
214
310
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
@@ -225,7 +321,21 @@ func Create[T, R any, F ResponseFunc[T, R]](ctx *context.Context, fn F, fnInput
225
321
return HandleCreate (ctx , resp , nil )
226
322
}
227
323
228
- // NoContent handles a generic response and error from a service call and sends a JSON response to the context.
324
+ // CreateHandler handles a create operation and sends a JSON response with the created resource to the client with status code of 201.
325
+ //
326
+ // See Create package-level function for more.
327
+ func CreateHandler [T , R any , F ResponseFunc [T , R ], I HandlerInputFunc [T ]](fn F , fnInput ... I ) context.Handler {
328
+ return func (ctx * context.Context ) {
329
+ inputs , ok := GetRequestInputs (ctx , fnInput )
330
+ if ! ok {
331
+ return
332
+ }
333
+
334
+ Create (ctx , fn , inputs ... )
335
+ }
336
+ }
337
+
338
+ // NoContent handles a generic response and error from a service call and sends a JSON response to the client.
229
339
// It returns a boolean value indicating whether the handle was successful or not.
230
340
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
231
341
// It sets the status code to 204 (No Content).
@@ -239,7 +349,21 @@ func NoContent[T any, F ResponseOnlyErrorFunc[T]](ctx *context.Context, fn F, fn
239
349
return NoContentOrNotModified (ctx , toFn , fnInput ... )
240
350
}
241
351
242
- // NoContent handles a generic response and error from a service call and sends a JSON response to the context.
352
+ // NoContentHandler handles a generic response and error from a service call and sends a JSON response to the client with status code of 204.
353
+ //
354
+ // See NoContent package-level function for more.
355
+ func NoContentHandler [T any , F ResponseOnlyErrorFunc [T ], I HandlerInputFunc [T ]](fn F , fnInput ... I ) context.Handler {
356
+ return func (ctx * context.Context ) {
357
+ inputs , ok := GetRequestInputs (ctx , fnInput )
358
+ if ! ok {
359
+ return
360
+ }
361
+
362
+ NoContent (ctx , fn , inputs ... )
363
+ }
364
+ }
365
+
366
+ // NoContent handles a generic response and error from a service call and sends a JSON response to the client.
243
367
// It returns a boolean value indicating whether the handle was successful or not.
244
368
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
245
369
// If the response is true, it sets the status code to 204 (No Content).
@@ -255,6 +379,20 @@ func NoContentOrNotModified[T any, F ResponseFunc[T, bool]](ctx *context.Context
255
379
return HandleUpdate (ctx , bool (resp ), nil )
256
380
}
257
381
382
+ // NoContentOrNotModifiedHandler handles a generic response and error from a service call and sends a JSON response to the client with status code of 204 or 304.
383
+ //
384
+ // See NoContentOrNotModified package-level function for more.
385
+ func NoContentOrNotModifiedHandler [T any , F ResponseFunc [T , bool ], I HandlerInputFunc [T ]](fn F , fnInput ... I ) context.Handler {
386
+ return func (ctx * context.Context ) {
387
+ inputs , ok := GetRequestInputs (ctx , fnInput )
388
+ if ! ok {
389
+ return
390
+ }
391
+
392
+ NoContentOrNotModified (ctx , fn , inputs ... )
393
+ }
394
+ }
395
+
258
396
// ReadPayload reads a JSON payload from the context and returns it as a generic type T.
259
397
// It also returns a boolean value indicating whether the read was successful or not.
260
398
// If the read fails, it sends an appropriate error response to the client.
0 commit comments