ShortyyDocs

Go (Golang) REST API Integration

Native Go integration using net/http, standard context cancellation, and zero third-party dependencies.

Go (Golang) REST API Integration

Shortyy's REST API can be consumed in Go with zero external dependencies using the standard library net/http and encoding/json.


Native Go Implementation

go
package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

type CreateLinkRequest struct {
	URL        string `json:"url"`
	ExpiresIn  string `json:"expires_in,omitempty"`
	CustomCode string `json:"custom_code,omitempty"`
}

type ShortLink struct {
	ID          string `json:"id"`
	Code        string `json:"code"`
	OriginalURL string `json:"original_url"`
	ShortURL    string `json:"short_url"`
	ClickCount  int64  `json:"click_count"`
	ExpiresAt   string `json:"expires_at"`
	CreatedAt   string `json:"created_at"`
}

type CreateLinkResponse struct {
	Link ShortLink `json:"link"`
}

func CreateShortLink(ctx context.Context, destURL, expiresIn string) (*ShortLink, error) {
	apiKey := os.Getenv("SHORTYY_API_KEY")
	if apiKey == "" {
		return nil, fmt.Errorf("SHORTYY_API_KEY not configured")
	}

	reqBody, err := json.Marshal(CreateLinkRequest{
		URL:       destURL,
		ExpiresIn: expiresIn,
	})
	if err != nil {
		return nil, err
	}

	req, err := http.NewRequestWithContext(ctx, "POST", "https://api.shortyy.com/v1/links", bytes.NewBuffer(reqBody))
	if err != nil {
		return nil, err
	}

	req.Header.Set("Authorization", "Bearer "+apiKey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusTooManyRequests {
		return nil, fmt.Errorf("rate limited by Shortyy (HTTP 429)")
	}

	if resp.StatusCode != http.StatusCreated {
		body, _ := io.ReadAll(resp.Body)
		return nil, fmt.Errorf("unexpected status %d: %s", resp.StatusCode, string(body))
	}

	var result CreateLinkResponse
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, err
	}

	return &result.Link, nil
}

func main() {
	ctx := context.Background()
	link, err := CreateShortLink(ctx, "https://golang.org", "2h")
	if err != nil {
		panic(err)
	}
	fmt.Printf("Created Go link: %s (%s)
", link.ShortURL, link.Code)
}