114 lines
2.5 KiB
Go
114 lines
2.5 KiB
Go
//go:build !change
|
|
|
|
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
|
|
"github.com/gorilla/handlers"
|
|
"github.com/gorilla/mux"
|
|
|
|
"gitlab.com/manytask/itmo-go/public/coverme/models"
|
|
"gitlab.com/manytask/itmo-go/public/coverme/utils"
|
|
)
|
|
|
|
type App struct {
|
|
router *mux.Router
|
|
db models.Storage
|
|
}
|
|
|
|
func New(db models.Storage) *App {
|
|
return &App{db: db}
|
|
}
|
|
|
|
func (app *App) Start(port int) {
|
|
app.initRoutes()
|
|
app.run(fmt.Sprintf(":%d", port))
|
|
}
|
|
|
|
func (app *App) initRoutes() {
|
|
app.router = mux.NewRouter()
|
|
app.router.HandleFunc("/", app.status).Methods("GET")
|
|
app.router.HandleFunc("/todo", app.list).Methods("GET")
|
|
app.router.HandleFunc("/todo/{id:[0-9]+}", app.getTodo).Methods("GET")
|
|
app.router.HandleFunc("/todo/{id:[0-9]+}/finish", app.finishTodo).Methods("POST")
|
|
app.router.HandleFunc("/todo/create", app.addTodo).Methods("POST")
|
|
}
|
|
|
|
func (app *App) run(addr string) {
|
|
loggedRouter := handlers.LoggingHandler(os.Stderr, app.router)
|
|
_ = http.ListenAndServe(addr, loggedRouter)
|
|
}
|
|
|
|
func (app *App) list(w http.ResponseWriter, r *http.Request) {
|
|
todos, err := app.db.GetAll()
|
|
if err != nil {
|
|
utils.ServerError(w)
|
|
return
|
|
}
|
|
|
|
_ = utils.RespondJSON(w, http.StatusOK, todos)
|
|
}
|
|
|
|
func (app *App) addTodo(w http.ResponseWriter, r *http.Request) {
|
|
req := &models.AddRequest{}
|
|
|
|
decoder := json.NewDecoder(r.Body)
|
|
if err := decoder.Decode(&req); err != nil {
|
|
utils.BadRequest(w, "payload is required")
|
|
return
|
|
}
|
|
defer func() { _ = r.Body.Close() }()
|
|
|
|
if req.Title == "" {
|
|
utils.BadRequest(w, "title is required")
|
|
return
|
|
}
|
|
|
|
todo, err := app.db.AddTodo(req.Title, req.Content)
|
|
if err != nil {
|
|
utils.ServerError(w)
|
|
return
|
|
}
|
|
|
|
_ = utils.RespondJSON(w, http.StatusCreated, todo)
|
|
}
|
|
|
|
func (app *App) getTodo(w http.ResponseWriter, r *http.Request) {
|
|
id, err := strconv.Atoi(mux.Vars(r)["id"])
|
|
if err != nil {
|
|
utils.BadRequest(w, "ID must be an int")
|
|
return
|
|
}
|
|
|
|
todo, err := app.db.GetTodo(models.ID(id))
|
|
if err != nil {
|
|
utils.ServerError(w)
|
|
return
|
|
}
|
|
|
|
_ = utils.RespondJSON(w, http.StatusOK, todo)
|
|
}
|
|
|
|
func (app *App) finishTodo(w http.ResponseWriter, r *http.Request) {
|
|
id, err := strconv.Atoi(mux.Vars(r)["id"])
|
|
if err != nil {
|
|
utils.BadRequest(w, "ID must be an int")
|
|
return
|
|
}
|
|
|
|
if err := app.db.FinishTodo(models.ID(id)); err != nil {
|
|
utils.ServerError(w)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (app *App) status(w http.ResponseWriter, r *http.Request) {
|
|
_ = utils.RespondJSON(w, http.StatusOK, "API is up and working!")
|
|
}
|