From 61a13c911471ffb34707327acf053cc492cdcb76 Mon Sep 17 00:00:00 2001 From: Florian Herrengt Date: Thu, 22 Dec 2022 00:33:47 +0100 Subject: [PATCH] structure files --- .gitignore | 3 +- .gitmodules | 3 -- api/handlers/events.go | 58 ++++++++++++++++++++++++++ api/handlers/ping.go | 11 +++++ api/router.go | 14 +++++++ go.mod | 3 +- go.sum | 4 ++ internal/nats.go | 27 ++++++++++++ main.go | 93 ++++-------------------------------------- schemas | 1 - 10 files changed, 127 insertions(+), 90 deletions(-) delete mode 100644 .gitmodules create mode 100644 api/handlers/events.go create mode 100644 api/handlers/ping.go create mode 100644 api/router.go create mode 100644 internal/nats.go delete mode 160000 schemas diff --git a/.gitignore b/.gitignore index a817828..14ab076 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ main gin-bin schemas -.env \ No newline at end of file +.env +vendor \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 445282f..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "schemas"] - path = schemas - url = git@github.com:nocodelytics/schemas.git diff --git a/api/handlers/events.go b/api/handlers/events.go new file mode 100644 index 0000000..a5a5dad --- /dev/null +++ b/api/handlers/events.go @@ -0,0 +1,58 @@ +package handlers + +import ( + "encoding/json" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" + nocodelytics_schemas "github.com/nocodelytics/schemas" + "github.com/nocodelytics/tracker-api/internal" + "github.com/xeipuuv/gojsonschema" +) + +var schema = nocodelytics_schemas.BuildEventsQueueInputSchemas() + +func TrackEvent(c *gin.Context) { + nc := internal.NewNatsConnection() + id, _ := uuid.NewRandom() + ipAddress := c.ClientIP() + userAgent := c.Request.Header.Get("User-Agent") + createdAt := time.Now().Format(time.RFC3339) + + data := gin.H{ + "id": id, + "ip": ipAddress, + "userAgent": userAgent, + "createdAt": createdAt, + } + + for k, v := range c.Request.URL.Query() { + data[k] = v[0] + } + + documentLoader := gojsonschema.NewGoLoader(data) + result, err := schema.Validate(documentLoader) + if err != nil { + panic(err) + } + + var errors []string + for _, val := range result.Errors() { + errors = append(errors, val.String()) + } + if !result.Valid() { + c.JSON(http.StatusBadRequest, gin.H{"errors": errors}) + return + } + + jsonData, _ := json.Marshal(data) + nc.Publish("events", []byte(jsonData)) + + c.JSON(http.StatusOK, gin.H{ + "ok": 1, + "id": id, + }) + +} diff --git a/api/handlers/ping.go b/api/handlers/ping.go new file mode 100644 index 0000000..02ff139 --- /dev/null +++ b/api/handlers/ping.go @@ -0,0 +1,11 @@ +package handlers + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func GetPing(ctx *gin.Context) { + ctx.Status(http.StatusOK) +} diff --git a/api/router.go b/api/router.go new file mode 100644 index 0000000..80991a3 --- /dev/null +++ b/api/router.go @@ -0,0 +1,14 @@ +package api + +import ( + "github.com/gin-gonic/gin" + "github.com/nocodelytics/tracker-api/api/handlers" +) + +func SetupRouter() *gin.Engine { + r := gin.Default() + + r.GET("/ping", handlers.GetPing) + r.GET("n.json", handlers.TrackEvent) + return r +} diff --git a/go.mod b/go.mod index 4798474..ccd7932 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module nocodelytics/tracker-api +module github.com/nocodelytics/tracker-api go 1.19 @@ -26,6 +26,7 @@ require ( github.com/nats-io/nats-server/v2 v2.9.8 // indirect github.com/nats-io/nkeys v0.3.0 // indirect github.com/nats-io/nuid v1.0.1 // indirect + github.com/nocodelytics/schemas v0.0.0-20221221224547-8be8499c3f14 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect diff --git a/go.sum b/go.sum index 6b33525..eb0bd05 100644 --- a/go.sum +++ b/go.sum @@ -53,6 +53,10 @@ github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nocodelytics/schemas v0.0.0-20221221221107-c5236fd5bc1a h1:nlu5umvJwOXVKtbtkNjF6L0zpQphjC2a1cuvguuqkkI= +github.com/nocodelytics/schemas v0.0.0-20221221221107-c5236fd5bc1a/go.mod h1:91blRjYsb6npZ571xhf6cLUVU85OvDzLxF+zPQEhra8= +github.com/nocodelytics/schemas v0.0.0-20221221224547-8be8499c3f14 h1:SfE9BvrMZguiMchZGjQVF1xYSEoLXihk9F5R/D8zotc= +github.com/nocodelytics/schemas v0.0.0-20221221224547-8be8499c3f14/go.mod h1:91blRjYsb6npZ571xhf6cLUVU85OvDzLxF+zPQEhra8= github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= diff --git a/internal/nats.go b/internal/nats.go new file mode 100644 index 0000000..db02e1a --- /dev/null +++ b/internal/nats.go @@ -0,0 +1,27 @@ +package internal + +import ( + "os" + "sync" + + "github.com/nats-io/nats.go" +) + +var ( + err error + nc *nats.Conn + once sync.Once +) + +func NewNatsConnection() *nats.Conn { + once.Do(func() { + nc, err = nats.Connect( + os.Getenv("NATS_URL"), + nats.UserInfo(os.Getenv("NATS_USER"), os.Getenv("NATS_PASSWORD")), + ) + if err != nil { + panic(err) + } + }) + return nc +} diff --git a/main.go b/main.go index 5c1a843..306f61a 100644 --- a/main.go +++ b/main.go @@ -2,93 +2,18 @@ package main import ( _ "embed" - "encoding/json" - "net/http" "os" - "time" - "github.com/gin-gonic/gin" - "github.com/google/uuid" - "github.com/nats-io/nats.go" - "github.com/xeipuuv/gojsonschema" + "github.com/nocodelytics/tracker-api/api" + "github.com/nocodelytics/tracker-api/internal" ) -//go:embed "schemas/jsonSchemas/eventsQueueInput.schema.json" -var eventsQueueInputSchema string - -func setupRouter() *gin.Engine { - r := gin.Default() - - r.GET("/", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "ok": 1, - "name": "tracker api", - }) - }) - sl := gojsonschema.NewSchemaLoader() - - jsonSchemaLoader := gojsonschema.NewStringLoader(eventsQueueInputSchema) - - schema, err := sl.Compile(jsonSchemaLoader) - if err != nil { - panic(err) - } - - nc, err := nats.Connect(os.Getenv("NATS_URL"), nats.UserInfo(os.Getenv("NATS_USER"), os.Getenv("NATS_PASSWORD"))) - if err != nil { - panic(err) - } - r.GET("/healthz", func(ctx *gin.Context) { - ctx.JSON(http.StatusOK, gin.H{ - "ok": 1, - }) - }) - r.GET("/n.json", func(c *gin.Context) { - - id, _ := uuid.NewRandom() - ipAddress := c.ClientIP() - userAgent := c.Request.Header.Get("User-Agent") - createdAt := time.Now().Format(time.RFC3339) - - data := gin.H{ - "id": id, - "ip": ipAddress, - "userAgent": userAgent, - "createdAt": createdAt, - } - - for k, v := range c.Request.URL.Query() { - data[k] = v[0] - } - - documentLoader := gojsonschema.NewGoLoader(data) - result, err := schema.Validate(documentLoader) - if err != nil { - panic(err) - } - - var errors []string - for _, val := range result.Errors() { - errors = append(errors, val.String()) - } - if !result.Valid() { - c.JSON(http.StatusBadRequest, gin.H{"errors": errors}) - return - } - - jsonData, _ := json.Marshal(data) - nc.Publish("events", []byte(jsonData)) - - c.JSON(http.StatusOK, gin.H{ - "ok": 1, - "id": id, - }) - - }) - return r -} - func main() { - r := setupRouter() - r.Run(":3001") + internal.NewNatsConnection() + r := api.SetupRouter() + port := os.Getenv("PORT") + if port == "" { + port = "3001" + } + r.Run(":" + port) } diff --git a/schemas b/schemas deleted file mode 160000 index f4254a9..0000000 --- a/schemas +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f4254a9c9f471047bbb88183401e04669d61472a