structure files
This commit is contained in:
parent
56b17b2b0b
commit
61a13c9114
|
@ -2,3 +2,4 @@ main
|
||||||
gin-bin
|
gin-bin
|
||||||
schemas
|
schemas
|
||||||
.env
|
.env
|
||||||
|
vendor
|
|
@ -1,3 +0,0 @@
|
||||||
[submodule "schemas"]
|
|
||||||
path = schemas
|
|
||||||
url = git@github.com:nocodelytics/schemas.git
|
|
|
@ -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,
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPing(ctx *gin.Context) {
|
||||||
|
ctx.Status(http.StatusOK)
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
3
go.mod
3
go.mod
|
@ -1,4 +1,4 @@
|
||||||
module nocodelytics/tracker-api
|
module github.com/nocodelytics/tracker-api
|
||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ require (
|
||||||
github.com/nats-io/nats-server/v2 v2.9.8 // indirect
|
github.com/nats-io/nats-server/v2 v2.9.8 // indirect
|
||||||
github.com/nats-io/nkeys v0.3.0 // indirect
|
github.com/nats-io/nkeys v0.3.0 // indirect
|
||||||
github.com/nats-io/nuid v1.0.1 // 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/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||||
|
|
4
go.sum
4
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/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 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
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 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
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=
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
93
main.go
93
main.go
|
@ -2,93 +2,18 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/nocodelytics/tracker-api/api"
|
||||||
"github.com/google/uuid"
|
"github.com/nocodelytics/tracker-api/internal"
|
||||||
"github.com/nats-io/nats.go"
|
|
||||||
"github.com/xeipuuv/gojsonschema"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//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() {
|
func main() {
|
||||||
r := setupRouter()
|
internal.NewNatsConnection()
|
||||||
r.Run(":3001")
|
r := api.SetupRouter()
|
||||||
|
port := os.Getenv("PORT")
|
||||||
|
if port == "" {
|
||||||
|
port = "3001"
|
||||||
|
}
|
||||||
|
r.Run(":" + port)
|
||||||
}
|
}
|
||||||
|
|
1
schemas
1
schemas
|
@ -1 +0,0 @@
|
||||||
Subproject commit f4254a9c9f471047bbb88183401e04669d61472a
|
|
Loading…
Reference in New Issue