Skip to content

Commit

Permalink
uwu
Browse files Browse the repository at this point in the history
  • Loading branch information
Quinntas committed Apr 28, 2024
1 parent 7ff2cfd commit e3a9b01
Show file tree
Hide file tree
Showing 17 changed files with 226 additions and 65 deletions.
46 changes: 46 additions & 0 deletions .air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
bin = "tmp\\main.exe"
cmd = "go build -o ./tmp/main.exe ./cmd"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
time = false

[misc]
clean_on_exit = false

[screen]
clear_on_rebuild = false
keep_scroll = true
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
*.so
*.dylib

./vendor
./vendor/*
vendor
vendor/*
.env
/tmp

.vscode
.idea
Expand Down
11 changes: 11 additions & 0 deletions api/shared/infra/router/routers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package sharedRouter

import (
"context"

v1Router "github.com/quinntas/go-rest-template/api/shared/infra/router/v1"
)

func InitRouters(ctx context.Context) {
v1Router.NewV1Router("/api/v1", ctx)
}
15 changes: 15 additions & 0 deletions api/shared/infra/router/v1/router.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package v1Router

import (
"context"
"net/http"

healthcheckUseCase "github.com/quinntas/go-rest-template/api/shared/useCases/healthCheck"
"github.com/quinntas/go-rest-template/internal/api/web"
)

func NewV1Router(path string, ctx context.Context) {
router := web.NewHttpRouter(path, ctx)

web.Route(router, http.MethodGet, "/health", ctx, healthcheckUseCase.Execute)
}
16 changes: 16 additions & 0 deletions api/shared/useCases/healthCheck/healthCheck.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package healthcheckUseCase

import (
"context"
"net/http"

"github.com/quinntas/go-rest-template/internal/api/utils"
"github.com/quinntas/go-rest-template/internal/api/web"
)

func Execute(request *http.Request, response http.ResponseWriter, ctx context.Context) error {
web.JsonResponse(response, http.StatusOK, &utils.Map[string]{
"message": "ok",
})
return nil
}
18 changes: 6 additions & 12 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,20 @@ package main
import (
"context"
"fmt"
"log"
"net/http"

sharedRouter "github.com/quinntas/go-rest-template/api/shared/infra/router"
"github.com/quinntas/go-rest-template/internal/api/utils/env"
"github.com/quinntas/go-rest-template/internal/api/web"
)

func execute(request *http.Request, response http.ResponseWriter, ctx context.Context) error {
web.JsonResponse(response, http.StatusOK, &map[string]string{
"message": "ok",
})
return nil
}

func main() {
envVariables := env.NewEnvVariables()

fmt.Println("[Server] running on", envVariables.Port)
ctx := context.WithValue(context.Background(), env.ENV_CTX_KEY, envVariables)

sharedRouter.InitRouters(ctx)

web.Route(http.MethodGet, "/", execute)
fmt.Println("[Server] running on", fmt.Sprintf("http://localhost:%s", envVariables.Port))

log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", envVariables.Port), web.ServerHandler(http.DefaultServeMux)))
web.Serve(envVariables.Port)
}
3 changes: 3 additions & 0 deletions internal/api/utils/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package utils

type Key string
7 changes: 7 additions & 0 deletions internal/api/utils/env/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package env

import "github.com/quinntas/go-rest-template/internal/api/utils"

const (
ENV_CTX_KEY utils.Key = "ENV"
)
7 changes: 3 additions & 4 deletions internal/api/utils/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import (
)

type EnvVariables struct {
Port string
Port string
}


func getEnv(key string, required bool) string {
value := os.Getenv(key)
if required && value == "" {
Expand All @@ -19,13 +18,13 @@ func getEnv(key string, required bool) string {
return value
}

func NewEnvVariables() EnvVariables{
func NewEnvVariables() EnvVariables {
err := godotenv.Load()
if err != nil {
panic(err)
}

return EnvVariables{
Port: getEnv("PORT", true),
Port: getEnv("PORT", true),
}
}
3 changes: 3 additions & 0 deletions internal/api/utils/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package utils

type Map[T interface{}] map[string]T
20 changes: 17 additions & 3 deletions internal/api/web/constants.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
package web

import (
"net/http"

"github.com/quinntas/go-rest-template/internal/api/utils"
)

const (
JSON_CTX_KEY = "JSON"
QUERY_CTX_KEY = "QUERY"
PATH_CTX_KEY = "PATH"
JSON_CTX_KEY utils.Key = "JSON"
QUERY_CTX_KEY utils.Key = "QUERY"
PATH_CTX_KEY utils.Key = "PATH"
)

func applyDefaultHeaders(w http.ResponseWriter) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
w.Header().Set("Server", "Encom-Backend/1.0.0 (Golang)")
w.Header().Set("X-Powered-By", "Encom")
}
29 changes: 21 additions & 8 deletions internal/api/web/errors.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,60 @@
package web

import "net/http"
import (
"net/http"

"github.com/quinntas/go-rest-template/internal/api/utils"
)

type HttpError struct {
status int
message string
body interface{}
body utils.Map[interface{}]
}

func (e *HttpError) Error() string {
return e.message
}

func (e *HttpError) ToJsonResponse(response http.ResponseWriter) {
e.body["message"] = e.message
JsonResponse(
response,
e.status,
&map[string]string{
"message": e.message,
},
&e.body,
)
}

func NewHttpError[T interface{}](status int, message string, body T) *HttpError {
func NewHttpError(status int, message string, body utils.Map[interface{}]) *HttpError {
return &HttpError{
status: status,
body: body,
message: message,
}
}

func UnprocessableEntity() *HttpError {
return NewHttpError(
http.StatusUnprocessableEntity,
"unprocessable entity",
utils.Map[interface{}]{
"hint": "please check the request's body",
},
)
}

func BadRequest() *HttpError {
return NewHttpError(
http.StatusBadRequest,
"bad request",
map[string]string{},
utils.Map[interface{}]{},
)
}

func NotFound() *HttpError {
return NewHttpError(
http.StatusNotFound,
"not found",
map[string]string{},
utils.Map[interface{}]{},
)
}
16 changes: 11 additions & 5 deletions internal/api/web/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package web
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
)
Expand Down Expand Up @@ -32,7 +33,7 @@ func handleError(err error, response http.ResponseWriter) {
}
}

func httpHandler(ctx context.Context, useCase UseCase) http.HandlerFunc {
func HttpHandler(ctx context.Context, useCase UseCase) http.HandlerFunc {
return func(response http.ResponseWriter, request *http.Request) {
err := parseForm(request)
if err != nil {
Expand All @@ -55,7 +56,7 @@ func httpHandler(ctx context.Context, useCase UseCase) http.HandlerFunc {
var data interface{}
err := json.NewDecoder(request.Body).Decode(&data)
if err != nil {
handleError(BadRequest(), response)
handleError(UnprocessableEntity(), response)
return
}
ctx = context.WithValue(ctx, JSON_CTX_KEY, data)
Expand All @@ -69,8 +70,13 @@ func httpHandler(ctx context.Context, useCase UseCase) http.HandlerFunc {
}
}

func Route(method string, path string, useCase UseCase) {
ctx := context.WithValue(context.Background(), PATH_CTX_KEY, path)
func notFoundHandler() {
http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
handleError(NotFound(), rw)
})
}

http.HandleFunc(method+" "+path, httpHandler(ctx, useCase))
func Route(router HttpRouter, method string, path string, ctx context.Context, useCase UseCase) {
ctx = context.WithValue(ctx, PATH_CTX_KEY, path)
http.HandleFunc(fmt.Sprintf("%s %s%s", method, router.path, path), HttpHandler(ctx, useCase))
}
Loading

0 comments on commit e3a9b01

Please sign in to comment.