genapi is a declarative HTTP client generator for Go, inspired by OpenFeign(https://github.com/OpenFeign/feign). It allows you to write HTTP clients using just interface definitions with annotations, eliminating the need for manual HTTP request handling.
- Declarative HTTP API client using Go interfaces
- Automatic JSON marshaling/unmarshaling
- Support for path/query parameters
- Custom header support
- Flexible response handling
- Context support for cancellation/timeouts
go get github.com/lexcao/genapi
- Define your API interface:
package api
import "github.com/lexcao/genapi"
//go:generate go run github.com/lexcao/genapi/cmd/genapi -file $GOFILE
// @BaseURL("https://api.github.com")
// @Header("Accept", "application/vnd.github.v3+json")
type GitHub interface {
genapi.Interface
// @GET("/repos/{owner}/{repo}/contributors")
Contributors(ctx context.Context, owner, repo string) ([]Contributor, error)
}
type Contributor struct {
Login string `json:"login"`
Contributions int `json:"contributions"`
}
- Generate the client code:
go generate ./api
- Use the client:
import (
"fmt"
"github.com/lexcao/genapi"
"your/package/to/api"
)
func main() {
client := genapi.New[api.GitHub]()
contributors, err := client.Contributors(context.Background(), "lexcao", "genapi")
if err != nil {
log.Fatalf("failed to get contributors: %v", err)
}
for _, c := range contributors {
fmt.Printf("%s: %d contributions\n", c.Login, c.Contributions)
}
}
The client can be configured with various options:
client := genapi.New[api.GitHub](
// Set dynamic BaseURL
genapi.WithBaseURL(os.GetEnv("API_ENDPOINT")),
// Add global headers
genapi.WithHeaders(map[string]string{
"Authorization": "Bearer " + token,
}),
)
Every interface must embed genapi.Interface
:
type MyAPI interface {
genapi.Interface
// your API methods here
}
Annotation | Description | Example |
---|---|---|
@BaseURL | Base URL for all API requests | @BaseURL("https://api.github.com") |
@Header | Global headers applied to all requests | @Header("Accept", "application/json") |
Annotation | Description | Example |
---|---|---|
@GET, @POST, etc | HTTP method and path | @GET("/users/{id}") |
@Query | URL query parameters | @Query("sort", "{sort}") |
@Header | Method-specific headers | @Header("Authorization", "Bearer {token}") |
genapi supports multiple response formats to fit your needs:
// No response body
func DeleteUser(ctx context.Context, id string) error
// Typed response with error handling
func GetUser(ctx context.Context, id string) (User, error)
// Raw response access
func GetRawResponse(ctx context.Context) (*genapi.Response, error)
// Must-style response (panics on error)
func MustGetUser(ctx context.Context, id string) User
You can access the Response from error
err := client.DeleteUser(ctx, id)
var apiErr *genapi.Error
if errors.As(err, &apiErr) {
// handle error with apiErr.Response
}
- Go 1.18 or higher
- Make (optional, for using Makefile commands)
- Clone the repository
git clone https://github.com/lexcao/genapi.git
cd genapi
- Install dependencies
go mod download
- Run tests
make test
make test
- Run testsmake lint
- Run lintermake coverage
- Generate test coverage reportmake generate
- Run go generatemake clean
- Clean up generated files
Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests.
This project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.