Decoupled API Architecture
Context
The portfolio's data layer could be co-located with the Next.js frontend using API routes (pages/api/*), which would simplify deployment to a single Vercel project. However, the content API serves multiple consumers beyond the portfolio site: an administrative interface for content management, AX (Agent Experience) endpoints for LLM consumption, and potential future integrations (mobile app, third-party aggregators). Coupling the API to the Next.js deployment cycle means every frontend change triggers a full redeploy of the data layer, and vice versa. Additionally, the MongoDB instance runs on a dedicated server with specific security group rules — exposing database credentials through Vercel's environment would create an unnecessary attack surface expansion.
Decision
Deploy the content API as an independent Node.js/Express application on a dedicated server (api.lucioduran.com), separate from the Next.js frontend hosted on Vercel. The API handles all CRUD operations, aggregation logic, and serves as the single source of truth for portfolio data. The frontend consumes the API exclusively through HTTP during build time (getStaticProps) and at request time (getServerSideProps for dynamic pages). CORS is configured to allow requests from lucioduran.com and localhost during development. The API has its own deployment pipeline, error monitoring, and scaling parameters independent of the frontend.
Consequences
Positive: Independent deploy cycles — frontend changes ship without touching the API, and API schema updates don't require a frontend redeploy. The API can serve multiple consumers with different authentication and rate-limiting policies. Database credentials never leave the API server's environment. The API can be horizontally scaled independently if needed. Build-time data fetching from the API creates a clear contract boundary that forces explicit versioning of data shapes. Negative: CORS configuration adds operational complexity and a potential failure mode. Network latency between Vercel's build infrastructure and the API server (~150ms) adds to build time. Two deployment pipelines mean two monitoring surfaces, two SSL certificate renewals, two sets of logs to aggregate. For a single-developer project, this operational overhead is non-trivial — but the architectural cleanliness and security posture justify it.
Predictions at Decision Time
Expected the independent deployment model to save significant time when iterating on frontend versus API changes separately. Predicted the CORS configuration would be a one-time setup cost. Assumed the operational overhead of two deployment pipelines would be manageable for a single developer. Predicted the API would gain at least 2-3 additional consumers beyond the portfolio site.
Measured Outcomes
The independent deployment model delivers value daily during active development — frontend deploys (triggered by Vercel on git push) never touch the API, and API updates (manual SSH deploy) never trigger frontend rebuilds. CORS was not a one-time cost: it required debugging twice (once for a new subdomain, once for the AI profile endpoint needing wildcard CORS). The dual-pipeline overhead is real but manageable — SSL renewal is automated via Let's Encrypt, and monitoring is handled through Vercel Analytics (frontend) and pm2 (API). The API now serves 4 consumers as predicted: portfolio site, admin UI, AX endpoints, and direct LLM agent queries.
Unknowns at Decision Time
Did not anticipate the AX (Agent Experience) use case at decision time. The API was designed for the portfolio site and admin UI — the fact that it became the backbone of the AI agent consumption strategy was an emergent benefit that validated the decoupling decision retrospectively. Also unknown: whether Vercel would improve its serverless function capabilities enough to make co-located API routes competitive. They have, but the security argument (credential isolation) remains decisive.
Reversibility Classification
Collapsing the API into Next.js API routes would require: migrating 12 Express route handlers to Next.js API route format, moving the MongoDB connection setup to Vercel's serverless context, exposing database credentials through Vercel environment variables, and reconfiguring all consumers (admin UI, AX endpoints) to point to the new location. The security regression (credentials leaving the dedicated server) makes this reversal undesirable beyond the technical effort. The admin UI would need a complete URL reconfiguration. Estimated effort: 15-20 hours plus risk assessment.
Strongest Counter-Argument
A monorepo with API routes in the same Next.js project would have halved operational complexity: one deploy pipeline, one monitoring surface, one SSL certificate, one set of environment variables. Vercel's serverless functions have improved significantly — cold starts are sub-100ms, and the DX of co-located API routes is excellent. For a single-developer project where all consumers are first-party, the security argument for credential isolation is arguably over-engineered. The counter-counter: the AX strategy (which didn't exist at decision time) now depends on the decoupled API's independence and stability, retroactively justifying what was originally an over-engineering decision.
Technical Context
- Database credentials isolated to API server
- Multiple API consumers
- Independent scaling