apigen
apigen
is a tool written in go that parses go structs and generates complete REST APIs
based on GORM ORM.
In short, it creates a complete REST API given a package where your models are. This avoid repetition since the structure of most services we build is similar, tedious and boring.
Features
- generates services for all structs in your models unless skipped in the configuration file(
apigen.toml
)
- Generates handler functions that call the underlying services for you.
- Wires routes for all your handlers.
- Automatic struct validation using the
go-validator/v10
package.
- Created Postgres database connection helper with sane defaults.
- Creates pagination handlers for your by default.
- Preloads all relationships(even nested relationships - for now) by default. Because the parser knows foreign keys and tree, we are able to do that for all
foreignKeys
and many2many
fields.
- Allows for customizing all queries by specifying optional Where, ordering, grouping, select
options ...services.Options
These options are passed to the callable handlers that are designed with the decorator pattern.
- Generates typescript interfaces for your models.
Installation
go install github.com/abiiranathan/apigen@latest
As a library
go get github.com/abiiranathan/apigen
Usage
Initialize project and create a configuration file apigen.toml
apigen init
The configuration file has the following format:
# Note that toml(v2) requires single quotes for strings
# This the path containing your go.mod
RootPkg='github.com/abiiranathan/apigen'
[Models]
# package containing your models. Even if in multiple files.
Pkg='github.com/abiiranathan/apigen/models'
# List of models to skip when generating services and handlers
Skip=['User', 'Payment']
[Output]
# The directory to put the generated code. (Default is current working directory)
OutDir='.'
# Name for your services package
ServiceName='services'
# Name for your handlers package
# Do not use routes.go (a routes.go file is generated along in the same folder.)
HandlersName='handlers'
Generate code
If apigen.toml is the root of your project.
apigen
Or
apigen config.toml
to specify the custom path to the configuration file.
Generate code using the API.
import (
"github.com/abiiranathan/apigen/config"
"github.com/abiiranathan/apigen/parser"
)
func main(){
cfg, err := config.LoadConfig("apigen.toml")
if err != nil {
panic(err)
}
// Generate all services, handlers and routes
if err := parser.GenerateCode(cfg); err != nil {
panic(err)
}
// Or generate only services
metadata := Parse(cfg.Models.Pkg)
if err := parser.GenerateGORMServices(cfg, metadata); err != nil{
panic(err)
}
}
Using the generated code
import(
// These will point to the generated code
"github.com/yourname/cool-api/gen/handlers"
"github.com/yourname/cool-api/gen/services"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm/logger"
)
func main() {
db, err := services.PostgresConnection(dsn, "Africa/kampala", logger.Silent)
if err != nil {
panic(err)
}
err = db.AutoMigrate(&models.User{}, ...more models)
if err != nil {
log.Fatalf("Error performing database migrations: %v\n", err)
}
app := fiber.New()
api := app.Group("/api/v1")
svc := services.NewService(db)
// Set up routes autogenerated for you
// Ignore this if you want to create custom routing.
handlers.SetupRoutes(api, handlers.New(db, svc))
app.Listen(":8000")
// Format for routes generated.
// GET /api/v1/users
// GET /api/v1/users/1
// POST /api/v1/users
// PUT /api/v1/users/1
// PATCH /api/v1/users/1
// DELETE /api/v1/users/1
}
see Examples for example usage.
TODO:
- Add tests
- Suport
database/sql
package.
- Expand on configuration options, so you can generate only what you want.
Disclaimer: This is intended for scafolding projects for simple to moderately complex APIs. If you need a lot of customization in routing, data fetching or very fast performance with custom drivers, this may not be for you. This does not mean it's slow for most projects.
Feature requests are welcome.