Skip to content

Commit

Permalink
Merge pull request #3 from ryichk/add-create-todo-api
Browse files Browse the repository at this point in the history
TODOを作成するAPIを追加
  • Loading branch information
ryichk authored Dec 30, 2024
2 parents e2c1361 + 0e2dcb5 commit a9986e4
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 2 deletions.
5 changes: 5 additions & 0 deletions api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.23.3

require (
github.com/MicahParks/keyfunc/v3 v3.3.5
github.com/go-playground/validator/v10 v10.23.0
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/jackc/pgx/v5 v5.7.2
github.com/labstack/echo/v4 v4.13.3
Expand All @@ -12,9 +13,13 @@ require (

require (
github.com/MicahParks/jwkset v0.5.19 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
Expand Down
12 changes: 12 additions & 0 deletions api/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ github.com/MicahParks/keyfunc/v3 v3.3.5/go.mod h1:SdCCyMJn/bYqWDvARspC6nCT8Sk74M
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
Expand All @@ -19,6 +29,8 @@ github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaa
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
Expand Down
2 changes: 1 addition & 1 deletion api/internal/handler/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (h *Handler) AcquireConnection(ctx context.Context, c echo.Context) (*UserI
return nil, err
}

conn, err := h.queries.AcquireConnection(ctx, h.pool)
conn, err := h.queries.AcquireConnection(ctx, h.pool, userID)
if err != nil {
return nil, err
}
Expand Down
45 changes: 45 additions & 0 deletions api/internal/handler/todo.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package handler

import (
"log"
"net/http"

"github.com/jackc/pgx/v5/pgtype"
"github.com/labstack/echo/v4"
"github.com/ryichk/todolist/api/internal/model"
)

func (h *Handler) ListTodos(c echo.Context) error {
Expand All @@ -22,3 +25,45 @@ func (h *Handler) ListTodos(c echo.Context) error {

return c.JSON(http.StatusOK, todos)
}

type CreateTodoRequestBody struct {
Title string `json:"title" validate:"required,min=1"`
Note pgtype.Text `json:"note"`
}

func (h *Handler) CreateTodo(c echo.Context) error {
ctx := c.Request().Context()

var body CreateTodoRequestBody
if err := c.Bind(&body); err != nil {
log.Printf("invalid request payload: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, "Invalid request payload")
}
if err := c.Validate(body); err != nil {
log.Printf("validation failed: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, "Validation failed")
}

userInfo, err := h.AcquireConnection(ctx, c)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
defer userInfo.Conn.Release()

createTodoParams := model.NewCreateTodoParams(
userInfo.UserID,
body.Title,
body.Note,
)
if todoID, err := h.queries.CreateTodo(ctx, userInfo.Conn, *createTodoParams); err != nil {
log.Printf("failed to create todo: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create todo")
} else {
log.Printf("Todo ID: %v", todoID)
}

response := map[string]string{
"message": "Successfully created a todo",
}
return c.JSON(http.StatusCreated, response)
}
8 changes: 7 additions & 1 deletion api/internal/model/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ package model
import (
"context"

"github.com/jackc/pgx/v5/pgtype"
"github.com/jackc/pgx/v5/pgxpool"
)

func (q *Queries) AcquireConnection(ctx context.Context, pool *pgxpool.Pool) (*pgxpool.Conn, error) {
func (q *Queries) AcquireConnection(ctx context.Context, pool *pgxpool.Pool, userID pgtype.UUID) (*pgxpool.Conn, error) {
conn, err := pool.Acquire(ctx)
if err != nil {
return nil, err
}

if _, err := conn.Exec(ctx, "SELECT set_config('app.current_user_id', $1, false)", userID); err != nil {
conn.Release()
return nil, err
}

return conn, nil
}
11 changes: 11 additions & 0 deletions api/internal/model/todo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package model

import "github.com/jackc/pgx/v5/pgtype"

func NewCreateTodoParams(userID pgtype.UUID, title string, note pgtype.Text) *CreateTodoParams {
return &CreateTodoParams{
UserID: userID,
Title: title,
Note: note,
}
}
14 changes: 14 additions & 0 deletions api/internal/model/validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package model

import "github.com/go-playground/validator/v10"

type CustomValidator struct {
Validator *validator.Validate
}

func (cv *CustomValidator) Validate(i interface{}) error {
if err := cv.Validator.Struct(i); err != nil {
return err
}
return nil
}
1 change: 1 addition & 0 deletions api/internal/server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ func PrivateRoutes(e *echo.Echo, h *handler.Handler, db *pgxpool.Pool, queries *
e.Use(AuthMiddleware())

e.GET("/todos", h.ListTodos)
e.POST("/todos", h.CreateTodo)
}
3 changes: 3 additions & 0 deletions api/internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"
"time"

"github.com/go-playground/validator/v10"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
Expand All @@ -27,6 +28,8 @@ func NewServer(db *pgxpool.Pool) (*echo.Echo, error) {
e.Server.ReadHeaderTimeout = 10 * time.Second
e.Server.WriteTimeout = 10 * time.Second

e.Validator = &model.CustomValidator{Validator: validator.New(validator.WithRequiredStructEnabled())}

queries := model.New()
h := handler.NewHandler(db, queries)

Expand Down

0 comments on commit a9986e4

Please sign in to comment.