Go-resty: A Simple HTTP Client

Wed, May 18, 2022 2-minute read

Go-resty: A Simple HTTP Client

When you need a decent HTTP client and don’t want to craft your own, then go-resty is a good choice. It is great when you need retries or an way to send requests based on the response, i.e. token expiration and renewal.

How I implement a JWT re-authentication check before each request.

import (

func NewAuth0() Auth0 {
	c := resty.New()
	c.OnBeforeRequest(func(client *resty.Client, request *resty.Request) error {
		if !IsTokenValid(c.Token) {
			r, err := Authenticate()
			if err != nil {
				return err
			request.Token = r.AccessToken
		return nil
	return Auth0{
		Groups: GroupApiStruct{
			client: RestClient{*c, *config.AppConfig(), c.Token},
func IsTokenValid(token string) bool {
	if token == "" {
		return false
	claims := &jwt.StandardClaims{}
	p := &jwt.Parser{}
	_, _, err := p.ParseUnverified(token, claims)
	if err != nil {
		return false
	err = claims.Valid()
	if err != nil {
		return false
	return true

func Authenticate() (AuthResponse, error) {
	c := config.AppConfig()
	client := resty.New()

	var result AuthResponse
	_, err := client.R().
		SetHeader("Content-Type", "application/json").
			GrantType:    "client_credentials",
			ClientId:     c.Secrets.Auth0ApiClientId,
			ClientSecret: c.Secrets.Auth0ApiClientSecret,
			Audience:     c.Secrets.Auth0ApiClientAudience,
	if err != nil {
		return AuthResponse{}, err
	return result, nil

type AuthResponse struct {
	AccessToken string `json:"access_token,omitempty"`
	ExpiresIn   int    `json:"expires_in,omitempty"`
	TokenType   string `json:"token_type,omitempty"`
	Scope       string `json:"scope,omitempty"`

type AuthPayload struct {
	GrantType    string `json:"grant_type,omitempty"`
	ClientId     string `json:"client_id,omitempty"`
	ClientSecret string `json:"client_secret,omitempty"`
	Audience     string `json:"audience,omitempty"`

This lets me check that the JWT is valid and if not, to request a new one from the service.

Coding this myself using just the standard library while possible is not a pragmatic use of my time. I vendor my code so even if resty went away tomorrow, it’ll keep working long enough to replace it.


#go #rest