lets-go:8.6 form parsing
This commit is contained in:
parent
1541305022
commit
4e40ef8ed9
@ -63,32 +63,22 @@ func (app *application) snippetCreate(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type snippetCreateForm struct {
|
type snippetCreateForm struct {
|
||||||
Title string
|
Title string `form:"title"`
|
||||||
Content string
|
Content string `form:"content"`
|
||||||
Expires int
|
Expires int `form:"expires"`
|
||||||
validator.Validator
|
validator.Validator `form:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// snippetCreatePost ...
|
// snippetCreatePost ...
|
||||||
func (app *application) snippetCreatePost(w http.ResponseWriter, r *http.Request) {
|
func (app *application) snippetCreatePost(w http.ResponseWriter, r *http.Request) {
|
||||||
err := r.ParseForm()
|
var form snippetCreateForm
|
||||||
|
|
||||||
|
err := app.decodePostForm(r, &form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.clientError(w, http.StatusBadRequest)
|
app.clientError(w, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
expires, err := strconv.Atoi(r.PostForm.Get("expires"))
|
|
||||||
if err != nil {
|
|
||||||
app.clientError(w, http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
form := snippetCreateForm{
|
|
||||||
Title: r.PostForm.Get("title"),
|
|
||||||
Content: r.PostForm.Get("content"),
|
|
||||||
Expires: expires,
|
|
||||||
}
|
|
||||||
|
|
||||||
form.CheckField(validator.NotBlank(form.Title), "title", "This field cannot be blank")
|
form.CheckField(validator.NotBlank(form.Title), "title", "This field cannot be blank")
|
||||||
form.CheckField(validator.MaxChars(form.Title, 100), "title", "This field cannot be more than 100 characters long")
|
form.CheckField(validator.MaxChars(form.Title, 100), "title", "This field cannot be more than 100 characters long")
|
||||||
form.CheckField(validator.NotBlank(form.Content), "content", "This field cannot be blank")
|
form.CheckField(validator.NotBlank(form.Content), "content", "This field cannot be blank")
|
||||||
|
@ -2,11 +2,14 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-playground/form/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// newTemplateData ...
|
// newTemplateData ...
|
||||||
@ -56,3 +59,24 @@ func (app *application) clientError(w http.ResponseWriter, status int) {
|
|||||||
func (app *application) notFound(w http.ResponseWriter) {
|
func (app *application) notFound(w http.ResponseWriter) {
|
||||||
app.clientError(w, http.StatusNotFound)
|
app.clientError(w, http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (app *application) ...
|
||||||
|
func (app *application) decodePostForm(r *http.Request, dst any) error {
|
||||||
|
err := r.ParseForm()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = app.formDecoder.Decode(dst, r.PostForm)
|
||||||
|
if err != nil {
|
||||||
|
var invalidDecoderError *form.InvalidDecoderError
|
||||||
|
|
||||||
|
if errors.As(err, &invalidDecoderError) {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"snippetbox.chaosfem.tw/internal/models"
|
"snippetbox.chaosfem.tw/internal/models"
|
||||||
|
|
||||||
|
"github.com/go-playground/form/v4"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ type application struct {
|
|||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
snippets *models.SnippetModel
|
snippets *models.SnippetModel
|
||||||
templateCache map[string]*template.Template
|
templateCache map[string]*template.Template
|
||||||
|
formDecoder *form.Decoder
|
||||||
}
|
}
|
||||||
|
|
||||||
// main it's the snippetbox webapp
|
// main it's the snippetbox webapp
|
||||||
@ -46,11 +48,14 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formDecoder := form.NewDecoder()
|
||||||
|
|
||||||
// setup the application
|
// setup the application
|
||||||
app := &application{
|
app := &application{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
snippets: &models.SnippetModel{DB: db},
|
snippets: &models.SnippetModel{DB: db},
|
||||||
templateCache: templateCache,
|
templateCache: templateCache,
|
||||||
|
formDecoder: formDecoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("starting server", slog.String("addr", *addr))
|
logger.Info("starting server", slog.String("addr", *addr))
|
||||||
|
@ -3,6 +3,7 @@ module snippetbox.chaosfem.tw
|
|||||||
go 1.21.4
|
go 1.21.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/go-playground/form/v4 v4.2.1 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||||
github.com/justinas/alice v1.2.0 // indirect
|
github.com/justinas/alice v1.2.0 // indirect
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/form/v4 v4.2.1 h1:HjdRDKO0fftVMU5epjPW2SOREcZ6/wLUzEobqUGJuPw=
|
||||||
|
github.com/go-playground/form/v4 v4.2.1/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U=
|
||||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||||
|
Loading…
Reference in New Issue
Block a user