Gompose
Gompose is a Go framework for quickly building RESTful APIs with support for multiple HTTP engines and databases (Postgres, MongoDB, etc). It provides features like CRUD handlers, entity hooks and middlewares.
Features
- Define entities as Go structs with tags
- Supports Postgres (GORM) and MongoDB adapters(more will be added in future!)
- Multiple HTTP engine adapters support(for now it's only Gin but more will be added in future)
- CRUD endpoints autogenerated per entity
- Middleware support (logging, rate limiting, etc)
- Custom Middlewares are also supported as well
- Entity lifecycle hooks (beforeSave, afterDelete, etc)
- Pagination, filtering, sorting support
- Authentication and Authorization with login and register routes(JWT for now but more will be added in future)
Installation
go get github.com/Lumicrate/gompose
Install Dependencies
go mod tidy
Usage
Setup
Setting up Gompose is so easy and quick you only have to tell what you want, here is the example of using Gompose!
package main
import (
"github.com/Lumicrate/gompose/core"
"github.com/Lumicrate/gompose/db/postgres"
"github.com/Lumicrate/gompose/http/gin"
"github.com/Lumicrate/gompose/middlewares"
)
// Define your entities
type User struct {
ID int `json:"id" gorm:"primaryKey;autoIncrement"` // make sure to include ID field for your entities
Name string `json:"name"`
Email string `json:"email"`
}
// define your hooks
func (u *User) BeforeCreate() error {
if !strings.Contains(u.Email, "@") {
return errors.New("invalid email format")
}
return nil
}
// create your custom middlewares
func CORSMiddleware() http.MiddlewareFunc {
return func(ctx http.Context) {
ctx.SetHeader("Access-Control-Allow-Origin", "*")
ctx.SetHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
ctx.SetHeader("Access-Control-Allow-Headers", "Authorization, Content-Type")
if ctx.Method() == "OPTIONS" {
ctx.SetStatus(204)
ctx.Abort()
return
}
ctx.Next()
}
}
func main() {
dsn := "host=localhost user=user password=password dbname=mydb port=5432 sslmode=disable" // set up the data source name
dbAdapter := postgres.New(dsn) // make your data adapter
httpEngine := ginadapter.New(8080) // make an http engine with the port
app := core.NewApp(). // create a new app
AddEntity(User{}). // add your entities
UseDB(dbAdapter). // register your database with your db adapter
UseHTTP(httpEngine). // register your http engine
RegisterMiddleware(middlewares.LoggingMiddleware()). // use built-in middlewares
RegisterMiddleware(CORSMiddleware()) // use your custom middleware
app.Run() // run your application
}
Auth Routes & Route Protection
By following the setup shown below, two authentication routes will automatically be registered:
POST /auth/login
POST /auth/register
These endpoints are enabled when you initialize the authProvider using the jwt.NewJWTAuthProvider() method.
You can customize how long JWT tokens remain valid using the SetTokenTTL() method:
authProvider := jwt.NewJWTAuthProvider("SecretKEY", dbAdapter).
SetUserModel(&User{}).
SetTokenTTL(time.Hour * 1) // Token valid for 1 hour
If you don’t set this explicitly, a default expiration time (3 days) will be used.
Additionally, route protection is applied when you define which HTTP methods should be secured using the crud.Protect() function. For example:
AddEntity(Office{}, crud.Protect("POST", "PUT", "DELETE"))
This ensures that POST, PUT, and DELETE operations on the Office entity are protected and require valid authentication.
Alternatively, you can secure all HTTP methods for a given entity using:
AddEntity(Office{}, crud.ProtectAll())
Example:
func main() {
// Configure Your database
dsn := "host=localhost user=username password=password dbname=mydb port=5432 sslmode=disable"
// Initialize DB adapter
dbAdapter := postgres.New(dsn)
// Initialize Gin HTTP adapter on port 8080
httpEngine := ginadapter.New(8080)
// Initialize JWT Provider
authProvider := jwt.NewJWTAuthProvider("SecretKEY", dbAdapter).
SetUserModel(&User{}) // Set your customized user model
// Create app instance
app := core.NewApp().
AddEntity(Office{}, crud.Protect("POST", "PUT", "DELETE")).
//AddEntity(Office{}, crud.ProtectAll()).
UseDB(dbAdapter).
UseHTTP(httpEngine).
UseAuth(authProvider)
app.Run()
}
Supported HTTP Engines
More HTTP Engines will be added in future also, switching HTTP engines is as simple as changing the adapter used in UseHTTP.
Supported Databases
- Postgres (via GORM)
- MongoDB (using official MongoDB Go driver)
Change database adapters via UseDB.
Middleware
You can register custom middleware by implementing the http.MiddlewareFunc interface.
Note: The middleware signature has changed to support standard chaining. Instead of directly handling ctx, middleware now wraps a next handler.
Correct Middleware Structure
func LoggingMiddleware() http.MiddlewareFunc {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(ctx http.Context) {
start := time.Now()
ctx.Next()
duration := time.Since(start)
log.Printf("[%s] %s %s %d %s",
ctx.Method(), ctx.Path(), ctx.RemoteIP(), ctx.Status(), duration)
next(ctx) // Call the next handler in the chain
}
}
Register middleware with:
app.RegisterMiddleware(LoggingMiddleware())
Entity Hooks
Implement hooks on entities to run code before/after certain events:
type User struct {
ID int `json:"id"`
//...
}
func (u *User) BeforeCreate() error {
// validation or processing
return nil
}
func (u *User) AfterDelete() error {
// cleanup or logging
return nil
}
Supported via query parameters on endpoints:
limit and offset for pagination
sort for sorting fields ascending/descending
- Filters via query keys matching entity fields
Contribution
Contributions are welcome! Please submit issues and pull requests.
License
MIT License