Skip to content

Commit

Permalink
Added second try for make simple app on golang
Browse files Browse the repository at this point in the history
  • Loading branch information
k8s4 committed Nov 10, 2024
1 parent f0bd553 commit c7ffce1
Show file tree
Hide file tree
Showing 11 changed files with 357 additions and 12 deletions.
6 changes: 4 additions & 2 deletions examples/golang/cource/06h_http/api/routes.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package api

import (
"golang/cource/06h_http/internals/app/handlers"

"github.com/gorilla/mux"
)

func CreateRoutes(userHandler *hadlers.UserHandler, carHandler *handlers.CarHandler) *mux.Router {
func CreateRoutes(userHandler *handlers.UsersHandler, carsHandler *handlers.CarsHandler) *mux.Router {
router := mux.NewRouter()
router.HandleFunc("/users/create", userHandler.Create).Methods("POST")
router.HandleFunc("/users/list", userHandler.List).Methods("GET")
Expand All @@ -14,6 +16,6 @@ func CreateRoutes(userHandler *hadlers.UserHandler, carHandler *handlers.CarHand
router.HandleFunc("/cars/list", carsHandler.List).Methods("GET")
router.HandleFunc("/cars/find/{id:[0-9]+}", carsHandler.Find).Methods("GET")

router.NotFoundHandler = r.NewRoute().HandleFunc(handlers.NotFound).GetHandler()
router.NotFoundHandler = router.NewRoute().HandlerFunc(handlers.NotFound).GetHandler()
return router
}
6 changes: 4 additions & 2 deletions examples/golang/cource/06h_http/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package main

import (
"context"
"golang/cource/06h_http/internals/app"
"golang/cource/06h_http/internals/cfg"
"os"
"os/signal"

log "github.com/sirupsen/logrus"

"golang/cource/06h_http/internals/app"
"golang/cource/06h_http/internals/cfg"
)

func main() {
config := cfg.LoadAndStoreConfig()

Expand Down
96 changes: 96 additions & 0 deletions examples/golang/cource/06h_http/internals/app/handlers/cars.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package handlers

import (
"encoding/json"
"errors"
"golang/cource/06h_http/internals/app/processors"
"net/http"
"strconv"
"strings"

"github.com/gorilla/mux"
)

type CarsHandler struct {
processor *processors.CarsProcessor
}

func NewCarsHandler(processor *processors.CarsProcessor) *CarsHandler {
handler := new(CarsHandler)
handler.processor = processor
return handler
}

func (handler *CarsHandler) Create(response http.ResponseWriter, request *http.Request) {
var newCar models.Cars
err := json.NewDecoder(request.Body).Decode(&newCar)
if err != nil {
WrapError(response, err)
return
}

err = handler.processor.CreateCar(newCar)
if err != nil {
WrapError(response, err)
return
}

var data = map[string]interface{}{
"result": "OK",
"data": "",
}

WrapOK(response, data)
}

func (handler *CarsHandler) List(response http.ResponseWriter, request *http.Request) {
vars := request.URL.Query()
var userIdFilter int64 = 0
if vars.Get("userid") != "" {
var err error
userIdFilter, err := strconv.ParseInt(vars.Get("userid"), 10, 64)
if err != nil {
WrapError(response, err)
return
}
}
list, err := handler.processor.ListCars(userIdFilter, strings.Trim(vars.Get("brand"), "\""),
strings.Trim(vars.Get("colour"), "\""), strings.Trim(vars.Get("license_plate"), "\""))
if err != nil {
WrapError(response, err)
}

var data = map[string]interface{}{
"result": "OK",
"data": list,
}

WrapOK(response, data)
}

func (handler *CarsHandler) Find(response http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
if vars["id"] == "" {
WrapError(response, errors.New("Missing ID."))
return
}

id, err := strconv.ParseInt(vars["id"], 10, 64)
if err != nil {
WrapError(response, err)
return
}

user, err := handler.processor.FindCar(id)
if err != nil {
WrapError(response, err)
return
}

var data = map[string]interface{}{
"result": "OK",
"data": user,
}

WrapOK(response, data)
}
31 changes: 31 additions & 0 deletions examples/golang/cource/06h_http/internals/app/handlers/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package handlers

import (
"encoding/json"
"fmt"
"net/http"
)

func WrapError(response http.ResponseWriter, err error) {
WrapErrorWithStatus(response, err, http.StatusBadRequest)
}

func WrapErrorWithStatus(response http.ResponseWriter, err error, httpStatus int) {
var data = map[string]string{
"result": "error",
"data": err.Error(),
}

res, _ := json.Marshal(data)
response.Header().Set("Content-Type", "application/json; charset=utf-8")
response.Header().Set("X-Content-Type-Options", "nosniff")
response.WriteHeader(httpStatus)
fmt.Fprintln(response, string(res))
}

func WrapOK(response http.ResponseWriter, data map[string]interface{}) {
res, _ := json.Marshal(data)
response.Header().Set("Content-Type", "application/json; charset=utf-8")
response.WriteHeader(http.StatusOK)
fmt.Fprintln(response, string(res))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package handlers

import (
"errors"
"net/http"
)

func NotFound(response http.ResponseWriter, request *http.Request) {
WrapErrorWithStatus(response, errors.New("Not found Handler"), http.StatusNotFound)
}
86 changes: 86 additions & 0 deletions examples/golang/cource/06h_http/internals/app/handlers/users.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package handlers

import (
"encoding/json"
"errors"
"golang/cource/06h_http/internals/app/processors"
"net/http"
"strconv"
"strings"

"github.com/gorilla/mux"
)

type UsersHandler struct {
processor *processors.UsersProcessor
}

func NewUsersHandler(processor *processors.UsersProcessor) *UsersHandler {
handler := new(UsersHandler)
handler.processor = processor
return handler
}

func (handler *UsersHandler) Create(response http.ResponseWriter, request *http.Request) {
var newUser models.User
err := json.NewDecoder(request.Body).Decode(&newUser)
if err != nil {
WrapError(response, err)
return
}

err = handler.processor.CreateUser(newUser)
if err != nil {
WrapError(response, err)
return
}

var data = map[string]interface{}{
"result": "OK",
"data": "",
}

WrapOK(response, data)
}

func (handler *UsersHandler) List(response http.ResponseWriter, request *http.Request) {
vars := request.URL.Query()
list, err := handler.processor.ListUsers(strings.Trim(vars.Get("name"), "\""))
if err != nil {
WrapError(response, err)
}

var data = map[string]interface{}{
"result": "OK",
"data": list,
}

WrapOK(response, data)
}

func (handler *UsersHandler) Find(response http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
if vars["id"] == "" {
WrapError(response, errors.New("Missing ID."))
return
}

id, err := strconv.ParseInt(vars["id"], 10, 64)
if err != nil {
WrapError(response, err)
return
}

user, err := handler.processor.FindUser(id)
if err != nil {
WrapError(response, err)
return
}

var data = map[string]interface{}{
"result": "OK",
"data": user,
}

WrapOK(response, data)
}
49 changes: 42 additions & 7 deletions examples/golang/cource/06h_http/internals/app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (
)

type AppServer struct {
config cfg.Cfg
ctx context.Context
srv *http.Server
config cfg.Cfg
ctx context.Context
srv *http.Server
db *pgxpool.Pool
}

func NewServer(config cfg.Cfg, ctx context.Context) *AppServer {
Expand All @@ -25,19 +26,53 @@ func NewServer(config cfg.Cfg, ctx context.Context) *AppServer {
func (server *AppServer) Serve() {
log.Println("Startung server")
log.Println(server.config.GetDBString())
db, err := pgxpool.Connect(server.ctx, server.config.GetDBString())
server.db, err := pgxpool.Connect(server.ctx, server.config.GetDBString())
if err != nil {
log.Fatalln(err)
}
defer db.Close()

carsStorage := db3.NewCarsStorage(db)
usersStorage := db3.NewUsersStorage(db)
carsStorage := db3.NewCarsStorage(server.db)
usersStorage := db3.NewUsersStorage(server.db)

carsProcessor := processors.NewCarsProcessor(carsStorage)
usersProcessor := processors.NewUsersProcessors(usersStorage)

carsHandler := handlers.NewCarsHandler(carsProcessor)
usersHandler := handlers.NewUsersHandler(usersProcessor)

routes := api.CreateRoutes(userHandler, carsHandler)
routes.Use(middleware.RequestLog)

server.srv = &http.Server{
Addr: ":" + server.confg.Port,
Handler: routes,
}

log.Println("Server started.")
err = server.srv.ListenAndServe()
if err != nil {
log.Fatalln(err)
}

return
}

func (server *AppServer) sShutdown() {
log.Println("Server stopped.")

ctxShutdown, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
server.db.Close()
defer func() {
cancel()
}()
var err error
if err = server.srv.Shutdown(ctxShutdown); err != nil {
log.Fatalf("Server shutdown failed: %v", err)
}

log.Println("Server exited properly.")

if err == http.ErrServerClosed {
err = nil
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package processors

import (
"errors"
)

type CarsProcessor struct {
storage *db.CarsStorage
}

func NewCarsProcessor(storage *db.CarsStorage) *CarsProcessor {
processor := new(CarsProcessor)
processor.storage = storage
return processor
}

func (processor *CarsProcessor) CreateCar(car models.Car) error {
if car.Colour == "" {
return errors.New("Colour should not be empty.")
}
if car.Brand == "" {
return errors.New("Brand should not be empty.")
}
if car.LicensePlate == "" {
return errors.New("License place should not be empty.")
}
if car.Owner.Id <= 0 {
return errors.New("Owner id shall be filled")
}

return processor.storage.CreateCar(car)
}

func (processor *CarsProcessor) FindCar(id int64) (models.Car, error) {
user := processor.storage.GetCarById(id)
if car.Id != id {
return car, errors.New("Car not found.")
}

return car, nil
}

func (processor *CarsProcessor) ListCars(userId int64, brandFilter string, colourFilter string, licenseFilter string) ([]models.Car, error) {
return processor.storage.GetCarsList(userId, brandFilter, colourFilter, licenseFilter), nil
}
Loading

0 comments on commit c7ffce1

Please sign in to comment.