Exavatar
API for dynamic generation and customization of avatars via URL parameters, designed to optimize profile management in scalable applications.
This document details the architecture, domain design, and technical implementation of Exavatar, a rendering engine and dynamic avatar generation API. This solution addresses a recurring friction point in web and mobile application development: managing default profile images or placeholders when the end user fails to provide one.
Utility and Workflow
The core problem this project solves is the absence of a temporary visual identity in user interfaces, which typically requires each development team to implement redundant logic for generating initials or conditionally loading images on the client side.
Exavatar shifts that responsibility entirely to the server. The tool acts as a REST API that, through structured URL parameters, instantly returns an avatar. It can serve a static asset from a predefined collection (e.g., animals or characters in WEBP/PNG format) or dynamically generate an SVG on the fly featuring the user’s initials over a solid color background.
The main application flow operates as follows:
- Request Reception: A client makes an HTTP GET request to the API with specific parameters (
set,id,size,format,color,text). - Domain Evaluation: The application core interprets the URL parameters to instantiate the main entity (
Avatar). If thetextparameter is provided, the application determines that it must compile and return a dynamically generated SVG. Otherwise, it validates the size, collection, and format attributes to construct a valid file path. - Repository Resolution: Depending on the execution environment (Development vs. Production), the application layer delegates the physical loading of the image to the corresponding infrastructure adapter (local or network-based).
- Response: The server returns the image binary or the SVG string with the correct HTTP headers and configured caching, minimizing computational load on subsequent requests.
Deep Analysis: Architecture and Data Modeling
The source code design (mainly located in src/core/) is a strict implementation of Domain-Driven Design (DDD) structured under the Hexagonal Architecture (Ports and Adapters) pattern. This technical decision is not by chance; it was adopted to completely isolate the business logic and generation rules from the presentation layer (Astro) and the infrastructure layer (network/file system).
General Architecture
The separation of concerns ensures that the core (domain) has no external dependencies, making the code inherently testable and scalable.
flowchart TD
subgraph Presentation ["Presentation (Astro / API Routes)"]
API["Route /api/avatar"]
end
subgraph ApplicationLayer ["Application Layer"]
AS["AvatarService"]
end
subgraph DomainLayer ["Domain Layer (Core)"]
A["Avatar : Entity"]
VO1["AvatarSize : Value Object"]
VO2["AvatarColor : Value Object"]
VO3["AvatarId : Value Object"]
VO4["AvatarSet : Value Object"]
VO5["AvatarText : Value Object"]
Repo["AvatarRepository : Port"]
A --> VO1
A --> VO2
A --> VO3
A --> VO4
A --> VO5
end
subgraph InfrastructureLayer ["Infrastructure Layer (Adapters)"]
LRepo["LocalAvatarRepository"]
GRepo["GitHubAvatarRepository"]
end
API --> AS
AS --> Repo
AS --> A
LRepo -.-> Repo
GRepo -.-> Repo
Data Modeling and Business Logic
The business logic resides in the Value Objects and the Aggregate Root entity (Avatar). These ensure that the application never processes an invalid state.
AvatarEntity: Orchestrates validation and transformation. It exposes theneedBuild()method, which intelligently determines the execution flow (reading a static file vs. generating an SVG) by evaluating whether theAvatarTextValue Object contains a valid value.- Value Objects:
AvatarSize: Validates allowed limits and resolutions (e.g., restricting between 16px and 512px).AvatarColor: Normalizes hexadecimal values and calculates secondary logic (such as automatic text contrast for SVG based on the luminance of the background color).AvatarId,AvatarSetandAvatarFormat: Ensure that the requested identifier belongs to a valid collection and that the output format is supported (webp,png,svg).
classDiagram
class Avatar {
+AvatarSet set
+AvatarId id
+AvatarSize size
+AvatarFormat format
+AvatarColor color
+AvatarText text
+String filepath
+String filename
+fromUrl(URL url) Avatar$
+needBuild() boolean
}
class AvatarService {
-AvatarRepository repository
+generate(URL url) Promise<AvatarResult>
}
class AvatarRepository {
<<interface>>
+load(Avatar avatar) Promise<AvatarResult>
}
AvatarService --> AvatarRepository : Uses
AvatarService ..> Avatar : Builds
The orchestrator service, AvatarService, applies dependency injection via the constructor. At runtime, the system injects GitHubAvatarRepository to fetch static files from the production repository, or LocalAvatarRepository to read from the local disk during development.
Technology Stack
The tool stack was strictly selected for performance and type control.
| Technology | Role in Architecture |
|---|---|
| Astro | Presentation framework and Server-Side Rendering (SSR). Handles API routing and delivers ultra-fast responses through the Edge Network without injecting JavaScript into the client. |
| TypeScript | Main programming language. Fundamental for modeling in the Domain layer, ensuring rigorous compliance with interfaces between ports and adapters. |
| Vitest | Unit testing environment. Allows testing the domain layer and AvatarService in complete isolation by injecting simulated repositories (mocks). |
| BiomeJS | Only static analysis tool (linter) and formatter. Configured to use tab indentation and single quotes, completely replacing Prettier and ESLint for higher execution speed. |
| Vercel | Deployment infrastructure. Uses Serverless/Edge Functions directly via @astrojs/vercel for processing and global CDN delivery of the generated images. |
The rigorous integration of DDD principles, advanced static typing, and a pure hexagonal architecture in a modern JavaScript environment results in a system with zero coupling between its rendering engine and its file distribution infrastructure. This abstraction allows scaling, switching hosting platforms, or adding new algorithmic generation formats without requiring alterations to the domain logic.