Skip to content

Instantly share code, notes, and snippets.

Created March 28, 2018 17:23
What would you like to do?
Go Lambda GeoIP
package main
import (
aegis ""
var db *geoip2.Reader
func main() {
// Load the database in main() in order to benefit from Lambda container re-use.
data, err := Asset("GeoLite2-City.mmdb")
if err == nil {
db, _ = geoip2.FromBytes(data)
defer db.Close()
// Handle API requests
router := aegis.NewRouter(fallThrough)
router.Handle("GET", "/", root)
// router.Listen()
// Handle RPCs
rpcRouter := aegis.NewRPCRouter()
rpcRouter.Handle("lookup", lookupProcedure)
handlers := aegis.Handlers{
Router: router,
RPCRouter: rpcRouter,
} else {
log.Println("Could not load GeoLite2-City.mmdb. Is it included in the binary?", err)
func fallThrough(ctx context.Context, evt *aegis.APIGatewayProxyRequest, res *aegis.APIGatewayProxyResponse, params url.Values) error {
res.StatusCode = 404
return nil
func root(ctx context.Context, evt *aegis.APIGatewayProxyRequest, res *aegis.APIGatewayProxyResponse, params url.Values) error {
record, err := lookup(evt.RequestContext.Identity.SourceIP)
res.JSON(200, record)
return err
func lookupProcedure(ctx context.Context, evt *map[string]interface{}) (map[string]interface{}, error) {
var resp map[string]interface{}
if evt != nil {
derefEvt := *evt
record, err := lookup(derefEvt["ipAddress"].(string))
if err == nil {
resp = structs.Map(record)
return resp, err
return resp, err
return resp, errors.New("no IP address passed to procedure")
func lookup(ipAddress string) (*geoip2.City, error) {
parsedIP := net.ParseIP(ipAddress)
return db.City(parsedIP)
Copy link

tmaiaroto commented Mar 28, 2018

From another Lambda, here's how you'd make the RPC.

// root is handling GET "/" in this case
func root(ctx context.Context, req *aegis.APIGatewayProxyRequest, res *aegis.APIGatewayProxyResponse, params url.Values) error {
	rpcPayload := map[string]interface{}{
		"_rpcName":  "lookup",
		"ipAddress": req.RequestContext.Identity.SourceIP,
	resp, rpcErr := aegis.RPC(ctx, "aegis_geoip", rpcPayload)
        // handle error in response if you like
	res.JSON(200, resp)
	return rpcErr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment