Fragments API
Secure Express microservice for authenticated fragment storage with AWS Cognito auth, S3/DynamoDB backends, format conversion, and full test coverage.
Overview
Fragments is a secure Node.js/Express microservice for authenticated binary and text fragment storage. It supports multiple content types, pluggable storage backends (memory, AWS S3, DynamoDB), format conversion, and was built with comprehensive test coverage using Jest, Supertest, and Hurl.
The Problem
The project was designed to practice building a production-quality microservice from scratch — proper auth, a clean storage abstraction, multiple content types, format conversion, and thorough testing at every layer.
What I Built
- 1A RESTful Express API for creating, reading, updating, and deleting fragments — supporting text, Markdown, HTML, JSON, and image content types.
- 2AWS Cognito bearer-token authentication with Passport.js — every request is authenticated against Cognito JWTs before any data is accessed.
- 3Hashed owner IDs — user identifiers are one-way hashed before storage so no PII is persisted alongside content.
- 4Storage abstraction layer with three backends: in-memory (for testing), AWS S3 (for binary data), and DynamoDB (for metadata) — swappable via environment variable.
- 5Format conversion endpoints: Markdown-to-HTML, image resizing and format conversion via the Sharp library.
- 6Comprehensive test coverage: unit tests with Jest, integration tests with Supertest, and end-to-end API tests with Hurl.
- 7Pino structured logging throughout — every request, auth event, and storage operation is logged in JSON format.
- 8Docker containerization with a multi-stage Dockerfile for lean production images.
Key Technical Decisions
Pluggable storage abstraction
The storage layer is defined as an interface implemented by three backends. Switching from in-memory (local dev) to S3+DynamoDB (production) requires only an environment variable change — no code changes.
AWS Cognito JWT auth
Every request is verified against a Cognito user pool using Passport.js. Tokens are validated cryptographically — not by round-tripping to a session store — so the service scales horizontally without sticky sessions.
Multi-layer test coverage
Unit tests cover the storage abstraction and business logic. Supertest integration tests cover every API endpoint. Hurl end-to-end tests run against the live service with real Cognito tokens — three layers of confidence.
Outcome
A well-tested, production-ready microservice demonstrating auth, cloud storage, containerization, and API design. Shows comfort with the AWS ecosystem and disciplined test-driven development.
What I Learned
Designing a storage abstraction that works identically in test (in-memory) and production (S3 + DynamoDB) taught me the value of interface-first design. The Sharp image conversion pipeline also introduced me to binary content handling in Node.js.