A production-ready RESTful API for managing books, built with Go and following best practices for project structure and organization.
- RESTful API with full CRUD operations (Create, Read, Update, Delete)
- Pagination with configurable page size (up to 100 items per page)
- Filtering & Search by title, author, or both
- Request ID Tracking for distributed tracing
- Clean Architecture with organized package structure
- Middleware Support including request ID, logging, CORS, and panic recovery
- Comprehensive Testing with unit tests and benchmarks
- Configuration Management via environment variables
- OpenAPI/Swagger Specification for API documentation
- Health Check Endpoint for monitoring
- Docker Support with multi-stage builds
- CI/CD Pipeline with GitHub Actions
- Thread-Safe in-memory storage with mutex protection
- Sample Data Seeding for quick testing
.
├── cmd/
│ └── api/
│ └── main.go # Application entry point
├── internal/
│ ├── config/
│ │ └── config.go # Configuration management
│ ├── handlers/
│ │ ├── books.go # Book HTTP handlers
│ │ └── health.go # Health check handler
│ ├── middleware/
│ │ ├── cors.go # CORS middleware
│ │ ├── logger.go # Request logging middleware
│ │ ├── recovery.go # Panic recovery middleware
│ │ └── requestid.go # Request ID middleware
│ ├── models/
│ │ ├── book.go # Book model and validation
│ │ ├── book_test.go # Book model tests
│ │ ├── errors.go # Domain errors
│ │ ├── filters.go # Filter models and logic
│ │ ├── filters_test.go # Filter tests
│ │ └── pagination.go # Pagination models
│ └── storage/
│ ├── storage.go # Storage interface
│ ├── memory.go # In-memory implementation
│ ├── memory_test.go # Storage tests
│ └── memory_bench_test.go # Performance benchmarks
├── pkg/
│ └── logger/
│ └── logger.go # Logging utilities
├── api/
│ └── openapi.yaml # OpenAPI 3.0 specification
├── scripts/
│ └── seed.go # Sample data seeder
├── .github/
│ └── workflows/
│ └── ci.yml # CI/CD pipeline
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Docker Compose configuration
├── Makefile # Common development tasks
├── .env.example # Example environment variables
├── go.mod # Go module definition
└── README.md # This file
GET /health- Check API health status
GET /books- Get all books (with pagination and filtering)- Query parameters:
page- Page number (default: 1)page_size- Items per page (default: 10, max: 100)title- Filter by title (case-insensitive, partial match)author- Filter by author (case-insensitive, partial match)search- Search in both title and author
- Query parameters:
POST /books- Create a new bookGET /books/{id}- Get a book by IDPUT /books/{id}- Update a book (full update)PATCH /books/{id}- Update a book (partial update)DELETE /books/{id}- Delete a book by ID
- Go 1.21 or higher
- Docker (optional)
- Make (optional)
- Clone the repository:
git clone https://github.com/codeforgood-org/golang-book-api.git
cd golang-book-api- Install dependencies:
go mod download- Copy the example environment file:
cp .env.example .env- Run the application:
go run cmd/api/main.goThe server will start on http://localhost:8080
The project includes a Makefile with common tasks:
make build # Build the application
make run # Run the application
make test # Run tests
make test-cover # Run tests with coverage
make bench # Run benchmarks
make seed # Seed sample data
make lint # Run linter
make clean # Clean build artifacts
make docker # Build Docker image
make help # Show available commandsBuild and run with Docker:
docker build -t book-api .
docker run -p 8080:8080 book-apiOr use Docker Compose:
docker-compose upcurl -X POST http://localhost:8080/books \
-H "Content-Type: application/json" \
-d '{
"title": "The Go Programming Language",
"author": "Alan A. A. Donovan"
}'Response:
{
"id": 123456,
"title": "The Go Programming Language",
"author": "Alan A. A. Donovan"
}curl http://localhost:8080/books?page=1&page_size=10Response:
{
"data": [
{
"id": 123456,
"title": "The Go Programming Language",
"author": "Alan A. A. Donovan"
}
],
"page": 1,
"page_size": 10,
"total": 1,
"total_pages": 1
}# Search in both title and author
curl "http://localhost:8080/books?search=Go"
# Filter by title
curl "http://localhost:8080/books?title=Programming"
# Filter by author
curl "http://localhost:8080/books?author=Donovan"
# Combine filters with pagination
curl "http://localhost:8080/books?author=Martin&page=1&page_size=5"curl http://localhost:8080/books/123456curl -X PUT http://localhost:8080/books/123456 \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title",
"author": "Updated Author"
}'curl -X DELETE http://localhost:8080/books/123456# Make sure the server is running first
make seedThis will create 20 sample books in the database.
curl http://localhost:8080/healthResponse:
{
"status": "ok"
}The application can be configured using environment variables:
| Variable | Description | Default |
|---|---|---|
SERVER_PORT |
Port to run the server on | 8080 |
LOG_LEVEL |
Logging level (info, warning, error) | info |
Run all tests:
go test ./...Run tests with coverage:
go test -cover ./...Run tests with detailed coverage report:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.outRun benchmarks:
make benchExample benchmark output:
BenchmarkMemoryStorage_Create-8 1000000 1024 ns/op 256 B/op 2 allocs/op
BenchmarkMemoryStorage_GetAll-8 5000000 312 ns/op 128 B/op 1 allocs/op
cmd/- Application entry pointsinternal/- Private application codeconfig/- Configuration managementhandlers/- HTTP request handlersmiddleware/- HTTP middlewaremodels/- Domain models and business logicstorage/- Data storage layer
pkg/- Public packages that can be imported by other projects
- Define the model in
internal/models/ - Add storage methods in
internal/storage/ - Create handler in
internal/handlers/ - Register route in
cmd/api/main.go - Add tests
- Keep packages focused and cohesive
- Use interfaces for dependencies
- Write tests for all business logic
- Use meaningful error messages
- Log important events
- Handle errors appropriately
- Use middleware for cross-cutting concerns
The project uses GitHub Actions for continuous integration. On every push:
- Code is checked out
- Dependencies are installed
- Tests are run
- Code is built
- Docker image is built (optional)
See .github/workflows/ci.yml for details.
The API is documented using OpenAPI 3.0 specification. You can find the spec at:
api/openapi.yaml
To view the documentation:
- Install a tool like Swagger UI or Redoc
- Open the
api/openapi.yamlfile
Online viewers:
- https://editor.swagger.io/ (paste the YAML content)
The application includes comprehensive benchmarks to ensure optimal performance:
- Create operations: ~1000 ns/op
- Read operations: ~300 ns/op
- Concurrent reads: Highly optimized with RWMutex
- Thread-safe: All operations are protected by mutexes
Run make bench to see detailed performance metrics.
- Database integration (PostgreSQL, MongoDB)
- Authentication and authorization (JWT, OAuth)
- Rate limiting middleware
- Caching layer (Redis)
- Full-text search
- Sorting options
- Metrics and monitoring (Prometheus)
- GraphQL support
- WebSocket support for real-time updates
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Project Link: https://github.com/codeforgood-org/golang-book-api