A clean, maintainable REST API for managing notes with pagination, filtering, and sorting capabilities. Built with Go, PostgreSQL, and following best practices for observability and testing.
- Full CRUD operations for notes
- Text search in title and content
- Tag-based filtering
- Pagination with configurable limits
- Structured logging with request IDs
- Prometheus metrics integration
- Health checks and graceful shutdown
- Docker support with multi-stage builds
- OpenAPI 3.0 specification
- Input validation and error handling
- Go 1.21+
- PostgreSQL 15+
- Docker & Docker Compose (for containerized setup)
-
Clone and setup:
git clone <repository-url> cd notes-api
-
Start dependencies:
make compose-up
-
Set environment variables:
cp .env.example .env # Edit .env with your configuration -
Run database migrations:
make migrate-up
-
Start the application:
make run
The API will be available at http://localhost:8080
# Start all services (database + API)
docker compose -f deployments/docker-compose.yml up -d
# View logs
docker compose -f deployments/docker-compose.yml logs -f notes-api
# Stop services
docker compose -f deployments/docker-compose.yml downhttp://localhost:8080
curl http://localhost:8080/healthzcurl -X POST http://localhost:8080/v1/notes \
-H "Content-Type: application/json" \
-d '{
"title": "My First Note",
"content": "This is the content of my note",
"tags": ["personal", "important"]
}'# Basic list
curl http://localhost:8080/v1/notes
# With pagination and search
curl "http://localhost:8080/v1/notes?page=1&page_size=10&q=search+term&tags=important&sort=updated_at&order=desc"curl http://localhost:8080/v1/notes/{note-id}curl -X PATCH http://localhost:8080/v1/notes/{note-id} \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title",
"is_archived": true
}'curl -X DELETE http://localhost:8080/v1/notes/{note-id}The application uses environment variables for configuration. See .env.example for all available options:
| Variable | Description | Default |
|---|---|---|
HTTP_ADDR |
Server listen address | :8080 |
DB_HOST |
PostgreSQL host | localhost |
DB_PORT |
PostgreSQL port | 5432 |
LOG_LEVEL |
Log level (debug/info/warn/error) | info |
METRICS_ENABLED |
Enable Prometheus metrics | true |
PAGINATION_MAX_LIMIT |
Maximum page size | 100 |
make help # Show all available commands
make build # Build the application
make run # Run the application locally
make test # Run all tests
make test-unit # Run unit tests only
make lint # Run golangci-lint
make compose-up # Start development services
make migrate-up # Run database migrations
make clean # Clean build artifactsnotes-api/
├── cmd/notes-api/ # Application entrypoint
├── internal/
│ ├── config/ # Configuration management
│ ├── db/ # Database connection and migrations
│ ├── http/ # HTTP router and middleware
│ ├── notes/ # Notes domain (models, service, repository, handlers)
│ ├── observability/ # Logging, metrics, tracing
│ └── version/ # Build version information
├── deployments/ # Docker and deployment files
├── docs/ # API documentation
├── .env.example # Environment variables template
├── Makefile # Development commands
└── README.md # This file
The application follows a layered architecture:
- HTTP Layer: Gin-based routing, middleware, request/response handling
- Service Layer: Business logic, validation, orchestration
- Repository Layer: Data access with PostgreSQL via pgx
- Infrastructure: Configuration, logging, metrics, database connections
# Run all tests
make test
# Run with coverage
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Run integration tests (requires running database)
make test-integrationPrometheus metrics are available at /metrics:
http_requests_total- HTTP request counterhttp_request_duration_seconds- HTTP request latencydb_query_duration_seconds- Database query latencybuild_info- Build information
Structured JSON logs include:
- Request ID for tracing
- HTTP method, path, status code
- Response times
- Error details
Start with monitoring stack:
docker compose -f deployments/docker-compose.yml --profile monitoring up -dAccess Prometheus at http://localhost:9090
- OpenAPI Spec:
docs/openapi.yaml - Swagger UI: Available when running locally (if configured)
Local performance targets:
- P50 < 20ms for CRUD operations
- P95 < 100ms for CRUD operations
- Supports concurrent requests with connection pooling
- Input validation with size limits
- Parameterized SQL queries
- Non-root container user
- CORS configuration for development
We welcome contributions! Please see our Contributing Guide for details on:
- How to set up the development environment
- Code style and standards
- Testing requirements
- Pull request process
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes and add tests
- Run tests and linting:
make test && make lint - Commit your changes:
git commit -m 'Add amazing feature' - Push to your branch:
git push origin feature/amazing-feature - Open a Pull Request
- API Documentation - OpenAPI 3.0 specification
- Contributing Guide - How to contribute to the project
- Security Policy - Security reporting and best practices
- Changelog - Version history and changes
- Bug Reports: Create an issue
- Feature Requests: Create an issue
- Questions: Start a discussion
This project is actively maintained and welcomes contributions. See the roadmap for planned features.
- Built with Go and Gin
- Database powered by PostgreSQL
- Containerized with Docker
- Metrics with Prometheus
This project is licensed under the MIT License - see the LICENSE file for details.
If this project helped you, please give it a star!