Skip to content

Backend service for storing and searching text snippets, with support for metadata (name, language, tags), visibility (public/private), and fuzzy search.

License

Notifications You must be signed in to change notification settings

PabloPavan/sniply_api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sniply API

Go Docker PostgreSQL Redis Observability Logs Proxy API Docs CI License

Overview

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).


Key Features

  • 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)

Tech Stack

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


Getting Started

Prerequisites

Make sure you have the following installed:

  • Go 1.24 or newer
  • Docker and Docker Compose
  • PostgreSQL 18 (or run via Docker)

Installation

Clone the Repository

git clone https://github.com/PabloPavan/_api.git
cd _api

Running with Docker (Recommended)

For 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.

API Overview

Health Check

GET /health

Returns service health status.


Authentication

Login

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.

API Keys

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.

Logout

POST /v1/auth/logout

Clears the session cookie.


API Keys (session only)

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

Users

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.


Snippets

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

Query Parameters (List)

  • q – search term (full‑text / fuzzy)
  • language – filter by language
  • tags – filter by tags
  • visibilitypublic or private
  • limit – pagination size
  • offset – pagination offset

Example – Create Snippet

POST /v1/snippets
{
  "name": "Hello World",
  "content": "print('Hello, world!')",
  "language": "python",
  "tags": ["example", "demo"],
  "visibility": "public"
}

Security Considerations

  • 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 Configuration

Session behavior is controlled by three environment variables:

  • SESSION_TTL – sliding window duration for active sessions
  • SESSION_REFRESH_BEFORE – refresh the session when it is within this window of expiry
  • SESSION_MAX_AGE – hard close absolute limit since login

Project Structure (High Level)

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

Contributing

Contributions are welcome.

Recommended workflow:

  1. Fork the repository
  2. Create a feature branch (feature/my-feature)
  3. Commit with clear messages
  4. Add tests when applicable
  5. Open a Pull Request with a clear description

Roadmap

  • Automated tests (unit and integration)
  • CI pipeline (lint, test, build)
  • API quotas
  • Extended observability dashboards
  • Deployment examples (Kubernetes, cloud providers)

License

This project is licensed under the MIT License. See the LICENSE file for details.


Author

Developed by Pablo Pavan.

About

Backend service for storing and searching text snippets, with support for metadata (name, language, tags), visibility (public/private), and fuzzy search.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published