Skip to content

Commit

Permalink
Refactor and add some cool stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
dhinogz committed Apr 30, 2024
1 parent 21c3d61 commit b2f562b
Show file tree
Hide file tree
Showing 15 changed files with 295 additions and 146 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MONGO_URI="mongodb+srv://challengeUser:[email protected]/getir-case-study?retryWrites=true"
LISTEN_ADDR=":4000"
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
.env
tmp/
bin/
go.sum
10 changes: 5 additions & 5 deletions config.go → config/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package config

import (
"errors"
Expand All @@ -7,17 +7,17 @@ import (
"github.com/joho/godotenv"
)

type config struct {
type Config struct {
MongoURI string
ListenAddr string
}

func loadConfig() (config, error) {
func LoadConfig() (Config, error) {
err := godotenv.Load()
if err != nil {
return config{}, errors.New("couldn't load env")
return Config{}, errors.New("couldn't load env")
}
var cfg config
var cfg Config
cfg.ListenAddr = os.Getenv("LISTEN_ADDR")
cfg.MongoURI = os.Getenv("MONGO_URI")

Expand Down
18 changes: 2 additions & 16 deletions store.go → db/db.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package db

import (
"context"
Expand All @@ -16,7 +16,7 @@ const (
)

type Store interface {
GetRecords(context.Context, RecordParams) Response
GetRecords(context.Context, RecordParams) ([]Record, error)
}

type MongoStore struct {
Expand Down Expand Up @@ -45,17 +45,3 @@ func NewMongoStore(mongoURI string) (*MongoStore, error) {
coll: client.Database(dbName).Collection(recordColl),
}, nil
}

func (s *MongoStore) GetRecords(ctx context.Context, params RecordParams) Response {
return Response{
Code: 0,
Msg: "",
Records: []RecordResponse{
{
Key: "",
CreatedAt: time.Now(),
TotalCount: 0,
},
},
}
}
19 changes: 19 additions & 0 deletions db/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package db

import (
"time"
)

type RecordParams struct {
StartDate string `json:"startDate"`
EndDate string `json:"endDate"`
MinCount int `json:"minCount"`
MaxCount int `json:"maxCount"`
}

// TODO: add bson fields
type Record struct {
Key string `json:"key"`
CreatedAt time.Time `json:"createdAt"`
TotalCount int `json:"totalCount"`
}
22 changes: 22 additions & 0 deletions db/records.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package db

import (
"context"
"time"
)

// TODO: actually call mongo database to fetch record
func (s *MongoStore) GetRecords(ctx context.Context, params RecordParams) ([]Record, error) {
return []Record{
{
Key: "1",
CreatedAt: time.Now(),
TotalCount: 1,
},
{
Key: "2",
CreatedAt: time.Now(),
TotalCount: 2,
},
}, nil
}
Binary file added docs/instructions1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/instructions2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc=
go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
91 changes: 0 additions & 91 deletions handlers.go

This file was deleted.

80 changes: 80 additions & 0 deletions handlers/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package handlers

import (
"encoding/json"
"errors"
"log/slog"
"net/http"

"github.com/dhinogz/go-assignment-w17/db"
)

type Handlers struct {
store db.Store
inMemory map[string]string
}

func NewHandlers(store db.Store) Handlers {
return Handlers{
store: store,
inMemory: make(map[string]string),
}
}

type Response struct {
Code int `json:"code"`
Msg string `json:"msg"`
}

func writeJSON(
w http.ResponseWriter,
status int,
data any,
headers http.Header,
) error {
js, err := json.MarshalIndent(data, "", "\t")
if err != nil {
return err
}

js = append(js, '\n')

for key, value := range headers {
w.Header()[key] = value
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
w.Write(js)

return nil
}

func readJSON(r *http.Request, data any) error {
decoder := json.NewDecoder(r.Body)
decoder.DisallowUnknownFields()
err := decoder.Decode(&data)
if err != nil {
return errors.New("could not read JSON")
}
return nil
}

func errorResponse(w http.ResponseWriter, status int, msg string, err error) {
slog.Error(msg, "err", err)
resp := Response{
Code: status,
Msg: msg,
}

err = writeJSON(w, status, resp, nil)
if err != nil {
internalServerError(w, "could not write JSON", err)
}
}

func internalServerError(w http.ResponseWriter, msg string, err error) {
slog.Error(msg, "err", err)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Internal Server Error"))
}
51 changes: 51 additions & 0 deletions handlers/in-memory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package handlers

import (
"fmt"
"net/http"
)

type InMemory struct {
Key string `json:"key"`
Value string `json:"value"`
}

func (h *Handlers) HandleInMemory(w http.ResponseWriter, r *http.Request) {
key := r.URL.Query().Get("key")
if key == "" {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "No query param for key")
return
}

value, ok := h.inMemory[key]
if !ok {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "Key does not exist")
return
}

data := InMemory{
Key: key,
Value: value,
}
err := writeJSON(w, http.StatusOK, data, nil)
if err != nil {
internalServerError(w, "could not write JSON", err)
}
}

func (h *Handlers) HandleCreateInMemory(w http.ResponseWriter, r *http.Request) {
var data InMemory
err := readJSON(r, data)
if err != nil {
errorResponse(w, http.StatusBadRequest, "error reading JSON", err)
}

h.inMemory[data.Key] = data.Value

err = writeJSON(w, http.StatusCreated, data, nil)
if err != nil {
internalServerError(w, "could not write JSON", err)
}
}
Loading

0 comments on commit b2f562b

Please sign in to comment.