fetchgo

package module
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2025 License: MIT Imports: 9 Imported by: 0

README

fetchgo

fetchgo is a minimal Go library designed to simplify HTTP requests across different runtimes. It provides a unified API that works in the browser with TinyGo + WebAssembly using syscall/js, and on the server using Go's standard net/http package. With fetchgo, you can write cross-platform HTTP logic once and run it anywhere.

Installation

go get github.com/cdvelop/fetchgo

Quick Start

package main

import (
    "fmt"
    "github.com/cdvelop/fetchgo"
)

func main() {
    client := &fetchgo.Client{
        BaseURL: "https://jsonplaceholder.typicode.com",
    }

    client.SendRequest("GET", "/posts/1", nil, func(result any, err error) {
        if err != nil {
            fmt.Printf("Error: %v\n", err)
            return
        }

        if body, ok := result.([]byte); ok {
            fmt.Printf("Response: %s\n", string(body))
        }
    })

    // Keep the program running to see the response
    select {}
}

API Reference

Core Types
Fetchgo struct

The main library struct. Currently used primarily for initialization.

type Fetchgo struct{}

func New() *Fetchgo
Client struct

The main HTTP client that handles requests across different platforms.

type Client struct {
    BaseURL        string      // Base URL for all requests, e.g., "https://api.example.com"
    defaultHeaders []string    // Internal storage for headers: ["key1", "value1", "key2", "value2"]
    TimeoutMS      int         // Request timeout in milliseconds
    RequestType    requestType // Default request type (e.g., RequestJSON, RequestRaw)
    encoder        encoder     // Optional: custom encoder for request bodies
}
encoder interface

Interface for encoding and decoding data, allowing pluggable serialization strategies.

type encoder interface {
    Encode(data any) ([]byte, error)
    Decode(data []byte, v any) error
}
Request Types

Constants that define how request bodies should be encoded:

  • RequestJSON - Encode request body as JSON (application/json)
  • RequestForm - Encode request body as form data (application/x-www-form-urlencoded)
  • RequestMultipart - Encode request body as multipart form data (multipart/form-data)
  • RequestRaw - Send request body as-is (raw bytes)
Client Methods
SendRequest(method, url, body, callback)

Sends an HTTP request asynchronously and invokes the callback with the result.

func (c *Client) SendRequest(method, url string, body any, callback func(any, error))

Parameters:

  • method - HTTP method (GET, POST, PUT, DELETE, etc.)
  • url - Request URL (can be relative if BaseURL is set, or absolute)
  • body - Request body (type depends on RequestType or custom encoder)
  • callback - Function called with response data and error

Example:

client.SendRequest("POST", "/users", userData, func(result any, err error) {
    if err != nil {
        log.Printf("Request failed: %v", err)
        return
    }

    if body, ok := result.([]byte); ok {
        fmt.Printf("Response: %s", string(body))
    }
})
AddHeader(key, value)

Adds a header to the client's default headers. Allows duplicate header keys.

func (c *Client) AddHeader(key, value string)

Example:

client := &fetchgo.Client{BaseURL: "https://api.example.com"}
client.AddHeader("Authorization", "Bearer token123")
client.AddHeader("X-Custom-Header", "value")
SetHeader(key, value)

Sets a header, ensuring there's at most one entry for the given key. Replaces existing values.

func (c *Client) SetHeader(key, value string)

Example:

client := &fetchgo.Client{BaseURL: "https://api.example.com"}
client.SetHeader("Authorization", "Bearer token123")
client.SetHeader("Authorization", "Bearer newtoken456") // Replaces previous value
Built-in Encoders
JSONEncoder

Implements JSON encoding/decoding for request and response bodies.

type JSONEncoder struct{}

func (e JSONEncoder) Encode(data any) ([]byte, error)
func (e JSONEncoder) Decode(data []byte, v any) error

Example:

client := &fetchgo.Client{
    BaseURL: "https://api.example.com",
    RequestType: fetchgo.RequestJSON,
}

// Send JSON data
data := map[string]string{"name": "John", "email": "john@example.com"}
client.SendRequest("POST", "/users", data, func(result any, err error) {
    // result will be []byte containing JSON response
})
RawEncoder

Implements raw byte encoding/decoding. Useful for sending files or binary data.

type RawEncoder struct{}

func (e RawEncoder) Encode(data any) ([]byte, error)
func (e RawEncoder) Decode(data []byte, v any) error

Example:

client := &fetchgo.Client{
    BaseURL: "https://api.example.com",
    RequestType: fetchgo.RequestRaw,
}

// Send raw bytes
rawData := []byte("raw binary data")
client.SendRequest("POST", "/upload", rawData, func(result any, err error) {
    // result will be []byte containing raw response
})

// Send file path (will be read as bytes)
client.SendRequest("POST", "/upload", "/path/to/file.txt", func(result any, err error) {
    // result will be []byte containing file contents
})
Configuration Options
BaseURL

Set the base URL for all requests. Relative URLs will be resolved against this base.

client := &fetchgo.Client{
    BaseURL: "https://api.example.com",
}

// These are equivalent:
// client.SendRequest("GET", "/users", nil, callback)
// client.SendRequest("GET", "https://api.example.com/users", nil, callback)
TimeoutMS

Set request timeout in milliseconds.

client := &fetchgo.Client{
    BaseURL: "https://api.example.com",
    TimeoutMS: 5000, // 5 second timeout
}
RequestType

Set the default request type for all requests.

client := &fetchgo.Client{
    BaseURL: "https://api.example.com",
    RequestType: fetchgo.RequestJSON,
}
Custom encoder

Use a custom encoder for specialized serialization needs.

client := &fetchgo.Client{
    BaseURL: "https://api.example.com",
    encoder: &CustomEncoder{},
}
Advanced Usage Examples
Multiple Headers
client := &fetchgo.Client{BaseURL: "https://api.example.com"}

// Add multiple headers
client.AddHeader("Authorization", "Bearer token123")
client.AddHeader("Content-Type", "application/json")
client.AddHeader("X-Client-Version", "1.0")

client.SendRequest("GET", "/data", nil, func(result any, err error) {
    // All headers will be sent with the request
})
Different Request Types
client := &fetchgo.Client{BaseURL: "https://httpbin.org"}

// JSON request
jsonData := map[string]string{"name": "John"}
client.SendRequest("POST", "/post", jsonData, func(result any, err error) {
    // Content-Type: application/json
})

// Raw request
rawData := []byte("raw data")
client.SendRequest("POST", "/post", rawData, func(result any, err error) {
    // Content-Type: application/octet-stream
})
Error Handling
client := &fetchgo.Client{BaseURL: "https://api.example.com"}

client.SendRequest("GET", "/users/999", nil, func(result any, err error) {
    if err != nil {
        // Handle different types of errors
        log.Printf("Request failed: %v", err)
        return
    }

    // Process successful response
    if body, ok := result.([]byte); ok {
        fmt.Printf("Response: %s", string(body))
    }
})

Platform Support

  • Server-side: Uses Go's standard net/http package
  • Browser (WASM): Uses syscall/js to call JavaScript's fetch API
  • Cross-compilation: Single codebase works across all platforms

Dependencies

  • github.com/cdvelop/tinystring - String utility functions

License

See LICENSE file for details.

Documentation

Index

Constants

View Source
const (
	// RequestJSON indicates that the request body should be encoded as JSON.
	RequestJSON requestType = "json"
	// RequestForm indicates that the request body should be form-urlencoded.
	RequestForm requestType = "form"
	// RequestMultipart indicates that the request body should be multipart/form-data.
	RequestMultipart requestType = "multipart"
	// RequestRaw indicates that the request body should be passed as-is.
	RequestRaw requestType = "raw"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Client added in v0.0.3

type Client struct {
	BaseURL string // Base URL for all requests, e.g., "https://api.example.com"

	TimeoutMS   int         // Request timeout in milliseconds.
	RequestType requestType // Default request type (e.g., RequestJSON, RequestRaw).
	// contains filtered or unexported fields
}

Client is a configurable HTTP client that works across WASM and standard Go. To create a client, initialize the struct directly, for example: client := &fetchgo.Client{ BaseURL: "https://api.example.com", RequestType: fetchgo.RequestJSON }

func (*Client) AddHeader added in v0.0.3

func (c *Client) AddHeader(key, value string)

AddHeader adds a header to the client's default headers. It will add the (key, value) pair even if the key already exists, potentially creating duplicate header keys.

func (*Client) SendRequest added in v0.0.3

func (c *Client) SendRequest(method, url string, body any, callback func(any, error))

SendRequest sends an HTTP request and invokes the callback with the result. It delegates the actual request logic to the environment-specific doRequest method. The entire operation, including the callback, runs in a new goroutine.

func (*Client) SetHeader added in v0.0.3

func (c *Client) SetHeader(key, value string)

SetHeader sets a header, ensuring there is at most one entry for the given key. If the header already exists, its value is replaced. If it does not exist, it is appended.

type Fetchgo

type Fetchgo struct{}

func New

func New() *Fetchgo

type JSONEncoder added in v0.0.3

type JSONEncoder struct{}

JSONEncoder implements the encoder interface for JSON data.

func (JSONEncoder) Decode added in v0.0.3

func (e JSONEncoder) Decode(data []byte, v any) error

Decode unmarshals the given JSON byte slice into the provided variable.

func (JSONEncoder) Encode added in v0.0.3

func (e JSONEncoder) Encode(data any) ([]byte, error)

Encode marshals the given data into a JSON byte slice.

type RawEncoder added in v0.0.3

type RawEncoder struct{}

RawEncoder implements the encoder interface for raw byte data. It acts as a pass-through for []byte and converts string to []byte.

func (RawEncoder) Decode added in v0.0.3

func (e RawEncoder) Decode(data []byte, v any) error

Decode handles raw data. It expects the destination `v` to be a pointer to a byte slice (*[]byte).

func (RawEncoder) Encode added in v0.0.3

func (e RawEncoder) Encode(data any) ([]byte, error)

Encode handles raw data. It expects data to be either []byte or string.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL