GoAPI is a Go library that provides a FastAPI-like development experience for Python, with automatic validation, dependency injection, customizable middleware, and automatic documentation.
- β Automatic data validation (similar to Pydantic)
- β Built-in Dependency Injection
- β Customizable middleware (CORS, Rate Limiting, Authentication, etc.)
- β Standardized responses with error handling
- β Automatic pagination
- β Automatic Swagger/OpenAPI documentation
- β Configurable rate limiting
- β Centralized error handling
- β Declarative syntax similar to FastAPI
go mod init your-project
go get github.com/esteban-ll-aguilar/goapipackage main
import (
"github.com/gin-gonic/gin"
"github.com/esteban-ll-aguilar/goapi/goapi"
"github.com/esteban-ll-aguilar/goapi/goapi/responses"
)
type User struct {
ID int `json:"id" validate:"required,min=1"`
Name string `json:"name" validate:"required,min=2,max=50"`
Email string `json:"email" validate:"required,email"`
}
func main() {
// Create configuration
config := goapi.DefaultConfig()
config.Title = "My API"
config.Description = "An API created with GoAPI"
// Create GoAPI instance
api := goapi.New(config)
// Define routes
api.GET("/users", func(c *gin.Context) {
users := []User{
{ID: 1, Name: "John", Email: "john@example.com"},
{ID: 2, Name: "Jane", Email: "jane@example.com"},
}
responses.Success(c, users)
})
// Run server
api.Run(":8080")
}type CreateUserRequest struct {
Name string `json:"name" validate:"required,min=2,max=50"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"required,min=18,max=120"`
}
api.POST("/users", func(c *gin.Context) {
var req CreateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
responses.BadRequest(c, "Invalid data format")
return
}
// Automatic validation
validator := validation.NewValidator()
if err := validator.ValidateStruct(req); err != nil {
validationErrors := validation.FormatValidationErrors(err)
var responseErrors []responses.ResponseValidationError
for _, ve := range validationErrors {
responseErrors = append(responseErrors, responses.ResponseValidationError{
Field: ve.Field,
Message: ve.Message,
Value: ve.Value,
})
}
responses.ValidationError(c, responseErrors)
return
}
// Create user
user := User{ID: 1, Name: req.Name, Email: req.Email}
responses.Created(c, user)
})// Register dependencies
userService := NewUserService()
api.RegisterSingletonDependency(func(c *gin.Context) (interface{}, error) {
return userService, nil
}, (*UserService)(nil))
// Use in handlers
api.GET("/stats", func(c *gin.Context) {
var service *UserService
if err := api.GetDependencyContainer().Resolve(c, &service); err != nil {
responses.InternalServerError(c, "Error resolving dependencies")
return
}
stats := service.GetStats()
responses.Success(c, stats)
})// CORS
api.AddCORS(middleware.CORSConfig{
AllowOrigins: []string{"http://localhost:3000"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},
})
// Rate Limiting
api.AddRateLimit(middleware.RateLimitConfig{
RequestsPerMinute: 100,
BurstSize: 10,
})
// Authentication
api.AddAuthentication("my-secret-key")
// Custom middleware
api.AddMiddleware(func(c *gin.Context) {
// Your custom logic
c.Next()
})// Success responses
responses.Success(c, data)
responses.Created(c, newUser)
responses.NoContent(c)
// Error responses
responses.BadRequest(c, "Invalid data")
responses.NotFound(c, "User not found")
responses.Unauthorized(c, "Invalid token")
responses.InternalServerError(c, "Internal error")
// Paginated responses
responses.Paginated(c, items, total, page, pageSize)
// Validation responses
responses.ValidationError(c, validationErrors)api.GET("/users", func(c *gin.Context) {
// Parse pagination parameters
pageStr := c.DefaultQuery("page", "1")
pageSizeStr := c.DefaultQuery("page_size", "10")
page, _ := strconv.Atoi(pageStr)
pageSize, _ := strconv.Atoi(pageSizeStr)
// Get data
users := userService.GetAll()
total := len(users)
// Apply pagination
start := (page - 1) * pageSize
end := start + pageSize
if end > total {
end = total
}
paginatedUsers := users[start:end]
responses.Paginated(c, paginatedUsers, total, page, pageSize)
})GoAPI automatically generates Swagger/OpenAPI documentation. You just need to add comments to your handlers:
// GetUsers retrieves all users
// @Summary Get users
// @Description Retrieves a paginated list of users
// @Tags users
// @Accept json
// @Produce json
// @Param page query int false "Page number"
// @Param page_size query int false "Page size"
// @Success 200 {object} responses.PaginatedResponse
// @Failure 400 {object} responses.ErrorResponse
// @Router /users [get]
func GetUsers(c *gin.Context) {
// Your implementation
}Once you run your API, you can access:
- Swagger UI:
http://localhost:8080/docs - ReDoc:
http://localhost:8080/redoc - Main page:
http://localhost:8080/
your-project/
βββ main.go
βββ go.mod
βββ go.sum
βββ handlers/
βββ users.go
βββ auth.go
When using GoAPI as a library:
import (
"github.com/esteban-ll-aguilar/goapi/goapi"
"github.com/esteban-ll-aguilar/goapi/goapi/middleware"
"github.com/esteban-ll-aguilar/goapi/goapi/responses"
"github.com/esteban-ll-aguilar/goapi/goapi/validation"
)config := goapi.APIConfig{
Title: "My Advanced API",
Description: "An API with all features",
Version: "2.0.0",
BasePath: "/api/v2",
Host: "api.mydomain.com",
Schemes: []string{"https"},
Debug: false,
Contact: goapi.Contact{
Name: "API Support",
URL: "https://mydomain.com/support",
Email: "support@mydomain.com",
},
License: goapi.License{
Name: "MIT",
URL: "https://opensource.org/licenses/MIT",
},
}
api := goapi.New(config)v1 := api.Group("/api/v1")
{
users := v1.Group("/users")
{
users.GET("", GetUsers)
users.GET("/:id", GetUser)
users.POST("", CreateUser)
users.PUT("/:id", UpdateUser)
users.DELETE("/:id", DeleteUser)
}
posts := v1.Group("/posts")
{
posts.GET("", GetPosts)
posts.POST("", CreatePost)
}
}GoAPI uses go-playground/validator with support for:
required- Required fieldmin=n- Minimum valuemax=n- Maximum valuelen=n- Exact lengthemail- Valid email formaturl- Valid URLgte=n- Greater than or equal tolte=n- Less than or equal tooneof=val1 val2- One of the specified values
type User struct {
ID int `json:"id" validate:"required,min=1"`
Name string `json:"name" validate:"required,min=2,max=50"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"required,min=18,max=120"`
Role string `json:"role" validate:"required,oneof=admin user guest"`
Website string `json:"website,omitempty" validate:"omitempty,url"`
}api.AddCORS(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
AllowCredentials: true,
})api.AddRateLimit(middleware.RateLimitConfig{
RequestsPerMinute: 60,
BurstSize: 10,
})api.AddAuthentication("your-jwt-secret-key")// Applied automatically
// X-Content-Type-Options: nosniff
// X-Frame-Options: DENY
// X-XSS-Protection: 1; mode=block| Feature | FastAPI (Python) | GoAPI (Go) |
|---|---|---|
| Automatic validation | β Pydantic | β go-playground/validator |
| Dependency Injection | β | β |
| Automatic documentation | β Swagger/OpenAPI | β Swagger/OpenAPI |
| Typed responses | β | β |
| Middleware | β | β |
| Rate Limiting | β | β |
| CORS | β | β |
| Pagination | β | β |
| Performance | Good | Excellent |
Check the examples/ directory for complete examples:
examples/basic_example.go- Basic usage exampleexamples/advanced_example.go- Complete example with all features
-
Install GoAPI:
go get github.com/esteban-ll-aguilar/goapi
-
Create your first project:
package main import ( "github.com/esteban-ll-aguilar/goapi/goapi" "github.com/gin-gonic/gin" ) func main() { api := goapi.New(goapi.DefaultConfig()) api.GET("/hello", func(c *gin.Context) { c.JSON(200, gin.H{"message": "Hello from GoAPI!"}) }) api.Run(":8080") }
-
Run your application:
go run main.go
-
Visit the documentation:
- API: http://localhost:8080
- Swagger: http://localhost:8080/docs
- ReDoc: http://localhost:8080/redoc
- Fork the project
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License. See the LICENSE file for details.
- FastAPI for the inspiration
- Gin for the base web framework
- go-playground/validator for validation
- Swagger for automatic documentation
If you have questions or need help:
- Contact the development team
GoAPI - Bringing FastAPI's simplicity to the Go ecosystem π
