2
\$\begingroup\$

I am writing a test web application in Golang.

Create post handler:

type NewPostReq struct {
    Title       string `validate:"required"`
    Description string `validate:"required"`
    Body        string `validate:"required"`
    Tags        []struct {
        Tag string `validate:"required"`
    } `validate:"min=2,dive"`
}

// PostResource the Post's json response
type PostResource struct {
    ID          uint   `json:"id"`
    Title       string `json:"title"`
    Description string `json:"description"`
    Body        string `json:"body"`
    Tags        []struct {
        ID  uint   `json:"id"`
        Tag string `json:"tag"`
    } `json:"tags"`
}

func CreatePost(c *Context) (err error) {
    req := new(NewPostReq)

    err = BindAndValidate(c.Request, req)
    if err != nil {
        return
    }

    post := new(Post)
    err = CopyTo(req, post)
    if err != nil {
        return
    }
    DB.Create(post)

    pr := new(PostResource)
    err = CopyTo(post, pr)
    if err != nil {
        return
    }

    err = c.JSON(201, pr)
    return
}

I am not sure if this is a good approach. I think I am repeating myself during error handling.

There is dependencies code:

type Handler func(*Context) error

func (mh Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    c := &Context{Response: w, Request: r}
    err := mh(c)

    if err != nil {
        switch e := err.(type) {
        case *HTTPError:
            c.JSON(e.HTTPStatusCode, e)
        default:
            http.Error(c.Response, e.Error(), http.StatusInternalServerError)
        }
    }
}

func Bind(r *http.Request, v interface{}) (err error) {
    err = json.NewDecoder(r.Body).Decode(v)
    return
}

func ValidateStruct(v interface{}) (err error) {
    errs := validate.Struct(v)
    if errs != nil {
        err = errs
        return
    }
    return nil
}

func BindAndValidate(r *http.Request, v interface{}) (err error) {
    err = Bind(r, v)
    if err != nil {
        return
    }
    err = ValidateStruct(v)
    if err != nil {
        err = NewFormValidationError(err.(validator.ValidationErrors))
    }
    return

}

// CopyTo copy data from struct to another struct
func CopyTo(from interface{}, to interface{}) (err error) {
    b, err := json.Marshal(from)
    if err != nil {
        return
    }
    err = json.Unmarshal(b, to)
    return
} 
\$\endgroup\$
  • \$\begingroup\$ Could you edit your post to use correct capitalization. And by the way, it's "Go" not "golang". \$\endgroup\$ – Dave C Jul 30 '15 at 17:27
  • \$\begingroup\$ sorry, my main language is not english. I wil try this \$\endgroup\$ – alioygur Jul 30 '15 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.