DEV Community

Cover image for New golang package to reduce code duplication in APIs
Alexis Viscogliosi
Alexis Viscogliosi

Posted on

3 2

New golang package to reduce code duplication in APIs

Hi Golang developers!

I just released a new package that will help you develop APIs in go.

Look at this code :

func (a *API) handleChangePassword(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    userID := vars["userID"]

    requestBody, err := ioutil.ReadAll(r.Body)
    if err != nil {
        errorResponse(w, http.StatusInternalServerError, "", err) // <-- your custom error logic that you write for 
                                                                  //      each project
        return
    }

    var requestData ChangePasswordRequest
    if err := json.Unmarshal(requestBody, &requestData); err != nil {
        errorResponse(w, http.StatusInternalServerError, "", err)
        return
    }

    if err = requestData.IsValid(); err != nil {
        errorResponse(w, http.StatusBadRequest, err.Error(), err)
        return
    }

    if err = a.app().ChangePassword(userID, requestData.OldPassword, requestData.NewPassword); err != nil {
        errorResponse(w, http.StatusBadRequest, err.Error(), err)
        return
    }

    jsonStringResponse(w, http.StatusOK, "{}") // <-- your custom code that your are write for each project
}
Enter fullscreen mode Exit fullscreen mode

This is often the code I see on Go projects. There is nothing wrong with writing this because it is very efficient and declarative.

But sometimes we would still like to focus a little more on what matters: business logic.

The version with KCD of this code now:

type ChangePasswordRequest struct {
    UserID string `path:"userID"`
    // ...
}

func (c *ChangePasswordRequest) Validate() error {
    // ...
}

func (a *API) handleChangePassword(request *ChangePasswordRequest) error {
    if err = a.app().ChangePassword(request.UserID, request.OldPassword, request.NewPassword); err != nil {
        return errors.Wrap(err, "unable to change password").WithKind(errors.KindInvalidArgument)
    }

    return nil
}
Enter fullscreen mode Exit fullscreen mode

As you can see the code is more concise and has less boilerplate, it is not more efficient because kcd uses reflection to achieve this simplicity.

If you want to play with this new toy this is the link of the package https://github.com/alexisvisco/kcd

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay