@@ -205,6 +205,7 @@ http.Handle("/handle", gate.ProtectFunc(func(w http.ResponseWriter, r *http.Requ
205
205
```
206
206
207
207
## Examples
208
+
208
209
### Protecting a handler using session cookie
209
210
If you want to only allow authenticated users to access a handler, you can use a custom token extractor function
210
211
combined with a client provider.
@@ -317,3 +318,183 @@ func main() {
317
318
provider := g8.NewClientProvider (getClientByTokenFunc).WithCustomCache (&customCache{})
318
319
}
319
320
```
321
+
322
+ ### Complete net/http server example
323
+ Here's a complete example showing how to build a REST API server using standard net/http:
324
+
325
+ ``` go
326
+ package main
327
+
328
+ import (
329
+ " encoding/json"
330
+ " fmt"
331
+ " log"
332
+ " net/http"
333
+
334
+ " github.com/TwiN/g8/v3"
335
+ )
336
+
337
+ func main () {
338
+ // Create authorization service with different clients and permissions
339
+ authService := g8.NewAuthorizationService ().
340
+ WithToken (" public-token" ). // Basic token with no special permissions
341
+ WithClient (g8.NewClient (" admin-token" ).WithPermission (" admin" )). // Admin token
342
+ WithClient (g8.NewClient (" user-token" ).WithPermissions ([]string {" read" , " write" })) // User token with specific permissions
343
+
344
+ // Create gate with authorization and rate limiting
345
+ gate := g8.New ().
346
+ WithAuthorizationService (authService).
347
+ WithRateLimit (100 ) // 100 requests per second
348
+
349
+ // Set up routes
350
+ mux := http.NewServeMux ()
351
+
352
+ // Public endpoints (no protection)
353
+ mux.HandleFunc (" /" , homeHandler)
354
+ mux.HandleFunc (" /health" , healthHandler)
355
+
356
+ // Protected endpoints using gate.ProtectFunc
357
+ mux.HandleFunc (" /api/profile" , gate.ProtectFunc (profileHandler))
358
+ mux.HandleFunc (" /api/data" , gate.ProtectFunc (dataHandler))
359
+
360
+ // Admin-only endpoints using gate.ProtectFuncWithPermission
361
+ mux.HandleFunc (" /api/admin/users" , gate.ProtectFuncWithPermission (adminUsersHandler, " admin" ))
362
+ mux.HandleFunc (" /api/admin/stats" , gate.ProtectFuncWithPermission (adminStatsHandler, " admin" ))
363
+
364
+ // Endpoints requiring specific permissions
365
+ mux.HandleFunc (" /api/read-data" , gate.ProtectFuncWithPermissions (readDataHandler, []string {" read" }))
366
+ mux.HandleFunc (" /api/write-data" , gate.ProtectFuncWithPermissions (writeDataHandler, []string {" write" }))
367
+ mux.HandleFunc (" /api/manage-data" , gate.ProtectFuncWithPermissions (manageDataHandler, []string {" read" , " write" }))
368
+
369
+ fmt.Println (" Server starting on :8080" )
370
+ fmt.Println (" Try these endpoints:" )
371
+ fmt.Println (" curl http://localhost:8080/" )
372
+ fmt.Println (" curl -H 'Authorization: Bearer public-token' http://localhost:8080/api/profile" )
373
+ fmt.Println (" curl -H 'Authorization: Bearer admin-token' http://localhost:8080/api/admin/users" )
374
+ fmt.Println (" curl -H 'Authorization: Bearer user-token' http://localhost:8080/api/read-data" )
375
+
376
+ log.Fatal (http.ListenAndServe (" :8080" , mux))
377
+ }
378
+
379
+ func homeHandler (w http .ResponseWriter , r *http .Request ) {
380
+ json.NewEncoder (w).Encode (map [string ]string {
381
+ " message" : " Welcome to the API" ,
382
+ " status" : " public" ,
383
+ })
384
+ }
385
+
386
+ func healthHandler (w http .ResponseWriter , r *http .Request ) {
387
+ w.Header ().Set (" Content-Type" , " application/json" )
388
+ json.NewEncoder (w).Encode (map [string ]string {" status" : " healthy" })
389
+ }
390
+
391
+ func profileHandler (w http .ResponseWriter , r *http .Request ) {
392
+ // Extract token from context (added by g8)
393
+ token , _ := r.Context ().Value (g8.TokenContextKey ).(string )
394
+
395
+ w.Header ().Set (" Content-Type" , " application/json" )
396
+ json.NewEncoder (w).Encode (map [string ]interface {}{
397
+ " message" : " Profile data" ,
398
+ " token" : token,
399
+ " user" : " authenticated user" ,
400
+ })
401
+ }
402
+
403
+ func dataHandler (w http .ResponseWriter , r *http .Request ) {
404
+ w.Header ().Set (" Content-Type" , " application/json" )
405
+ json.NewEncoder (w).Encode (map [string ]interface {}{
406
+ " data" : []string {" item1" , " item2" , " item3" },
407
+ })
408
+ }
409
+
410
+ func adminUsersHandler (w http .ResponseWriter , r *http .Request ) {
411
+ w.Header ().Set (" Content-Type" , " application/json" )
412
+ json.NewEncoder (w).Encode (map [string ]interface {}{
413
+ " users" : []map [string ]interface {}{
414
+ {" id" : 1 , " name" : " Alice" , " role" : " admin" },
415
+ {" id" : 2 , " name" : " Bob" , " role" : " user" },
416
+ },
417
+ })
418
+ }
419
+
420
+ func adminStatsHandler (w http .ResponseWriter , r *http .Request ) {
421
+ w.Header ().Set (" Content-Type" , " application/json" )
422
+ json.NewEncoder (w).Encode (map [string ]interface {}{
423
+ " stats" : map [string ]int {
424
+ " total_users" : 1000 ,
425
+ " active_users" : 750 ,
426
+ " requests_today" : 15000 ,
427
+ },
428
+ })
429
+ }
430
+
431
+ func readDataHandler (w http .ResponseWriter , r *http .Request ) {
432
+ w.Header ().Set (" Content-Type" , " application/json" )
433
+ json.NewEncoder (w).Encode (map [string ]interface {}{
434
+ " message" : " Reading data..." ,
435
+ " data" : " sensitive read-only data" ,
436
+ })
437
+ }
438
+
439
+ func writeDataHandler (w http .ResponseWriter , r *http .Request ) {
440
+ w.Header ().Set (" Content-Type" , " application/json" )
441
+ json.NewEncoder (w).Encode (map [string ]interface {}{
442
+ " message" : " Data written successfully" ,
443
+ " action" : " write" ,
444
+ })
445
+ }
446
+
447
+ func manageDataHandler (w http .ResponseWriter , r *http .Request ) {
448
+ w.Header ().Set (" Content-Type" , " application/json" )
449
+ json.NewEncoder (w).Encode (map [string ]interface {}{
450
+ " message" : " Full data management access" ,
451
+ " actions" : []string {" read" , " write" , " delete" , " modify" },
452
+ })
453
+ }
454
+ ```
455
+
456
+ ### Using http.Handle vs http.HandleFunc
457
+ g8 supports both ` http.Handle ` and ` http.HandleFunc ` patterns:
458
+
459
+ ``` go
460
+ package main
461
+
462
+ import (
463
+ " net/http"
464
+ " github.com/TwiN/g8/v3"
465
+ )
466
+
467
+ // Custom handler implementing http.Handler interface
468
+ type CustomHandler struct {
469
+ message string
470
+ }
471
+
472
+ func (h *CustomHandler ) ServeHTTP (w http .ResponseWriter , r *http .Request ) {
473
+ w.Write ([]byte (h.message ))
474
+ }
475
+
476
+ func main () {
477
+ gate := g8.New ().WithAuthorizationService (
478
+ g8.NewAuthorizationService ().WithToken (" my-token" ),
479
+ )
480
+
481
+ mux := http.NewServeMux ()
482
+
483
+ // Using http.Handle with gate.Protect
484
+ customHandler := &CustomHandler{message: " Hello from custom handler" }
485
+ mux.Handle (" /custom" , gate.Protect (customHandler))
486
+
487
+ // Using http.HandleFunc with gate.ProtectFunc
488
+ mux.HandleFunc (" /function" , gate.ProtectFunc (func (w http.ResponseWriter , r *http.Request ) {
489
+ w.Write ([]byte (" Hello from handler function" ))
490
+ }))
491
+
492
+ // Multiple protection levels
493
+ mux.Handle (" /admin" , gate.ProtectWithPermissions (customHandler, []string {" admin" }))
494
+ mux.HandleFunc (" /user" , gate.ProtectFuncWithPermission (func (w http.ResponseWriter , r *http.Request ) {
495
+ w.Write ([]byte (" User area" ))
496
+ }, " user" ))
497
+
498
+ http.ListenAndServe (" :8080" , mux)
499
+ }
500
+ ```
0 commit comments