github.com/blend/go-sdk@v1.20220411.3/examples/web/middleware/main.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package main 9 10 import ( 11 "fmt" 12 "math/rand" 13 "sync" 14 15 "github.com/blend/go-sdk/graceful" 16 "github.com/blend/go-sdk/logger" 17 "github.com/blend/go-sdk/web" 18 ) 19 20 // Any is a type alias for interface{} 21 type Any = interface{} 22 23 // APIController implements a simple controller. 24 type APIController struct { 25 db map[string]Any 26 dbLock sync.Mutex 27 } 28 29 // Register adds routes for the controller to the app. 30 func (ac *APIController) Register(app *web.App) { 31 app.GET("/api", ac.all, ac.randomFailure) 32 app.GET("/api/:key", ac.get, ac.randomFailure) 33 app.POST("/api/:key", ac.post, ac.randomFailure) 34 app.PUT("/api/:key", ac.put, ac.randomFailure) 35 app.DELETE("/api/:key", ac.delete, ac.randomFailure) 36 } 37 38 func (ac *APIController) randomFailure(action web.Action) web.Action { 39 return func(r *web.Ctx) web.Result { 40 if rand.Int()%2 == 0 { 41 return web.JSON.InternalError(fmt.Errorf("random error")) 42 } 43 return action(r) 44 } 45 } 46 47 func (ac *APIController) ensureDB() { 48 if ac.db == nil { 49 ac.db = map[string]Any{} 50 } 51 } 52 53 func (ac *APIController) all(r *web.Ctx) web.Result { 54 ac.dbLock.Lock() 55 defer ac.dbLock.Unlock() 56 ac.ensureDB() 57 58 return web.JSON.Result(ac.db) 59 } 60 61 func (ac *APIController) get(r *web.Ctx) web.Result { 62 ac.dbLock.Lock() 63 defer ac.dbLock.Unlock() 64 ac.ensureDB() 65 66 value, hasValue := ac.db[web.StringValue(r.Param("key"))] 67 if !hasValue { 68 return web.JSON.NotFound() 69 } 70 return web.JSON.Result(value) 71 } 72 73 func (ac *APIController) post(r *web.Ctx) web.Result { 74 ac.dbLock.Lock() 75 defer ac.dbLock.Unlock() 76 ac.ensureDB() 77 78 body, err := r.PostBody() 79 if err != nil { 80 return web.JSON.InternalError(err) 81 } 82 ac.db[web.StringValue(r.Param("key"))] = string(body) 83 return web.JSON.OK() 84 } 85 86 func (ac *APIController) put(r *web.Ctx) web.Result { 87 ac.dbLock.Lock() 88 defer ac.dbLock.Unlock() 89 ac.ensureDB() 90 91 _, hasValue := ac.db[web.StringValue(r.Param("key"))] 92 if !hasValue { 93 return web.JSON.NotFound() 94 } 95 96 body, err := r.PostBody() 97 if err != nil { 98 return web.JSON.InternalError(err) 99 } 100 ac.db[web.StringValue(r.Param("key"))] = string(body) 101 102 return web.JSON.OK() 103 } 104 105 func (ac *APIController) delete(r *web.Ctx) web.Result { 106 ac.dbLock.Lock() 107 defer ac.dbLock.Unlock() 108 ac.ensureDB() 109 110 key := web.StringValue(r.Param("key")) 111 _, hasValue := ac.db[key] 112 if !hasValue { 113 return web.JSON.NotFound() 114 } 115 delete(ac.db, key) 116 return web.JSON.OK() 117 } 118 119 func main() { 120 log := logger.All() 121 app := web.MustNew(web.OptLog(log)) 122 app.Register(new(APIController)) 123 graceful.Shutdown(app) 124 }