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  }