Sniply API is a modern, production‑ready backend service for storing, searching, and managing text and code snippets. It is designed with a strong focus on simplicity, performance, and clean architecture, making it suitable for personal tools, developer platforms, or integration into larger systems.
The project follows best practices commonly found in high‑quality open‑source backend repositories: clear domain boundaries, explicit configuration, containerized workflows, and first‑class API documentation.
At runtime, all traffic flows through Traefik (TLS + routing), the API talks to PostgreSQL, and observability is handled via OpenTelemetry + Grafana (Prometheus, Loki, Tempo).
- Session‑based authentication (HttpOnly cookies)
- API keys with scoped access (
read,write,read_write) - User management (signup, login, profile management)
- Full CRUD for snippets
- Snippet visibility control (
public/private) - Advanced search using PostgreSQL Full‑Text Search and pg_trgm (fuzzy search)
- Filtering by language, tags, and visibility
- Pagination support
- Redis‑backed snippet cache and login rate limiting
- OpenAPI / Swagger documentation
- Docker‑first development and deployment
- Ready for observability (metrics, logs, traces)
| Category | Technology |
|---|---|
| Language | Go |
| HTTP Router | chi |
| Database | PostgreSQL 18 |
| Cache / Sessions | Redis |
| Search | Full‑Text Search + pg_trgm |
| Migrations | golang-migrate |
| Containerization | Docker, Docker Compose |
| API Docs | Swagger / OpenAPI |
| Proxy | Traefik |
| Observability | OpenTelemetry + Grafana (Prometheus, Loki, Tempo, Alloy) |
For more details and flow diagrams, see here
Make sure you have the following installed:
- Go 1.24 or newer
- Docker and Docker Compose
- PostgreSQL 18 (or run via Docker)
git clone https://github.com/PabloPavan/_api.git
cd _apiFor development, debugging, and advanced Docker workflows (including debug images and troubleshooting), please refer to README.dev.md. That document describes the recommended and correct way to run Sniply API with Docker in development environments.
GET /healthReturns service health status.
POST /v1/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "password"
}Response:
Sets a Set-Cookie header with the HttpOnly session cookie.
{
"session_expires_at": "2025-01-01T00:00:00Z",
"csrf_token": "..."
}For state-changing requests using the session cookie, send X-CSRF-Token with the value returned on login.
Authenticated endpoints (except login/logout) also accept API keys.
Create an API key (requires session auth + CSRF token):
POST /v1/auth/api-keys
X-CSRF-Token: <csrf_token>
{
"name": "ci",
"scope": "read_write"
}Response returns the key once:
{
"id": "key_...",
"token": "sk_...",
"token_prefix": "sk_...",
"scope": "read_write"
}Use the API key:
GET /v1/snippets
X-API-Key: sk_...Scopes: read allows GET/HEAD/OPTIONS; write allows POST/PUT/PATCH/DELETE; read_write allows both.
API keys are stored only as hashes; the raw token is not persisted and is shown once at creation.
POST /v1/auth/logoutClears the session cookie.
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/auth/api-keys |
Create API key |
| GET | /v1/auth/api-keys |
List API keys |
| DELETE | /v1/auth/api-keys/{id} |
Revoke API key |
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/users |
Create a new user |
| GET | /v1/users/me |
Get current user |
| PUT | /v1/users/me |
Update current user |
| DELETE | /v1/users/me |
Delete current user |
All /me endpoints require authentication.
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/snippets |
List snippets with filters |
| GET | /v1/snippets/{id} |
Get snippet by ID |
| POST | /v1/snippets |
Create a snippet |
| PUT | /v1/snippets/{id} |
Update a snippet |
| DELETE | /v1/snippets/{id} |
Delete a snippet |
q– search term (full‑text / fuzzy)language– filter by languagetags– filter by tagsvisibility–publicorprivatelimit– pagination sizeoffset– pagination offset
POST /v1/snippets
{
"name": "Hello World",
"content": "print('Hello, world!')",
"language": "python",
"tags": ["example", "demo"],
"visibility": "public"
}- All protected endpoints require a valid session cookie
- Sessions use HttpOnly cookies (avoid localStorage tokens)
- Session requests that change data require
X-CSRF-Token - Passwords are stored hashed
- Always run behind HTTPS in production
- Validate environment variables before startup
Session behavior is controlled by three environment variables:
SESSION_TTL– sliding window duration for active sessionsSESSION_REFRESH_BEFORE– refresh the session when it is within this window of expirySESSION_MAX_AGE– hard close absolute limit since login
src/
cmd/ # Application entrypoints
internal/ # Application core (domain, services, repositories)
migrations/ # Database migrations
observability/ # Grafana/Prometheus/Loki/Tempo configs
compose.base.yml # Base Docker Compose
compose.dev.yml # Development overrides
compose.prod.yml # Production overrides
Dockerfile
Contributions are welcome.
Recommended workflow:
- Fork the repository
- Create a feature branch (
feature/my-feature) - Commit with clear messages
- Add tests when applicable
- Open a Pull Request with a clear description
- Automated tests (unit and integration)
- CI pipeline (lint, test, build)
- API quotas
- Extended observability dashboards
- Deployment examples (Kubernetes, cloud providers)
This project is licensed under the MIT License. See the LICENSE file for details.
Developed by Pablo Pavan.