Building a Scalable Intermediate API Layer for Framer CMS Integration
#Backend

Building a Scalable Intermediate API Layer for Framer CMS Integration

Backend Reporter
5 min read

A custom Node.js API bridge was created to decouple front‑end applications from Framer CMS, improving consistency, performance, and security while supporting multi‑channel content distribution for hospitality brands.

Problem: Direct Framer CMS calls break scalability and consistency

Hotels and resorts often need to push the same news, events, and image galleries to a website, a mobile app, and partner portals. When each client talks directly to Framer CMS, several issues appear:

  • Latency spikes – every request hits the CMS, which is optimized for authoring, not for high‑throughput public traffic.
  • Inconsistent data shapes – different front‑ends request fields in different ways, leading to duplicated transformation logic.
  • Security surface area – exposing the CMS API keys to many clients increases the risk of credential leakage.
  • Limited caching – browsers can only cache what the CMS returns; there is no shared edge layer that can serve stale‑but‑valid data during CMS outages.

The team needed a pattern that would let content stay authoritative in Framer while giving downstream services a fast, stable, and secure way to consume it.


Solution Approach: An intermediate Node.js API layer

Architecture overview

Featured image

  1. Framer CMS (source of truth) – authors edit content through Framer’s UI; the data lives in Framer’s managed datastore.
  2. Sync service (Node.js) – a scheduled job pulls the latest collections via the official Framer Server API and writes them to a lightweight PostgreSQL instance. This creates a read‑only replica that can be queried without affecting the authoring workflow.
  3. REST façade – custom Express endpoints expose normalized resources such as /news, /events, /galleries. Each endpoint returns a stable JSON contract that matches the front‑end expectations.
  4. Cache tier – Redis stores the most recent query results for 5‑15 minutes, depending on the content type. Cache keys embed the content version from Framer, so a cache miss automatically triggers a fresh DB read.
  5. PHP client library – a thin wrapper around curl that hides pagination, error handling, and token refresh. Front‑ends import the library, call fetchNews() or fetchEvent(id), and receive ready‑to‑render objects.

Key design decisions

Decision Reasoning
Separate sync job vs. on‑demand fetch Pull‑based sync guarantees that the API layer never throttles Framer during traffic spikes. It also lets us apply bulk transformations once, rather than per request.
PostgreSQL as intermediate store Relational schema gives us strong consistency guarantees (ACID) for the snapshot we expose. It also supports complex joins for featured‑content queries without pulling the whole document graph each time.
Redis with version‑aware keys Guarantees that stale data is never served after a content update. The version tag is part of the cache key, so a new publish automatically invalidates the old entry.
Express + TypeScript Strong typing enforces the contract between API and PHP client, reducing runtime mismatches.
HTTPS + API‑key guard The façade requires a signed token that the PHP client injects. Tokens are short‑lived (15 min) and rotated by the sync service, limiting exposure if a key leaks.

Trade‑offs and scalability implications

Consistency model

The system follows an eventual consistency pattern from the perspective of the public API. After a content author publishes in Framer, the sync job may take up to a minute to pull the change. For most hospitality use cases (news listings, event calendars) a sub‑minute lag is acceptable. If a brand requires true read‑your‑writes semantics, the sync interval can be reduced to seconds, at the cost of higher API quota consumption on Framer.

Scaling reads

  • Horizontal scaling – The Express service is stateless; adding more containers behind a load balancer instantly raises request capacity.
  • Cache hit ratio – With typical news pages, the Redis layer serves > 95 % of reads, keeping database CPU under 20 % even during promotional spikes.
  • Database sharding – Should the number of content types grow beyond a few hundred thousand rows, PostgreSQL can be partitioned by content type, preserving query performance.

Scaling writes (sync side)

The sync job runs as a cron‑like worker in a Kubernetes pod. It fetches only changed collections using Framer’s If-Modified-Since header, minimizing bandwidth. In a worst‑case scenario (full content refresh), the job streams JSON directly into the DB via COPY, which can ingest millions of rows in under a minute on a modest instance.

Trade‑off summary

Aspect Benefit Cost
Latency – sub‑100 ms for cached reads Improves UX on mobile and low‑bandwidth devices Requires operational overhead for Redis cluster
Security – no direct Framer keys in clients Reduces attack surface Adds token‑generation service and rotation logic
Consistency – eventual, < 1 min lag Acceptable for news/events Not suitable for real‑time inventory updates
Complexity – extra sync layer Decouples authoring from delivery More moving parts, need monitoring and alerts

Practical takeaways for similar projects

  1. Never expose a third‑party CMS directly to public traffic unless the provider explicitly supports edge caching and rate limiting.
  2. Introduce a version tag (e.g., framerVersion) in every cached payload; it makes cache invalidation deterministic.
  3. Keep the public contract simple – flat JSON objects with explicit field names avoid the need for front‑end adapters.
  4. Pair the API with a language‑specific client. The PHP wrapper in this project abstracts pagination and token handling, letting developers focus on rendering rather than HTTP plumbing.
  5. Monitor sync latency – a Grafana dashboard that shows “time since last successful pull” quickly surfaces publishing delays.

Conclusion

By inserting a Node.js‑based intermediate API layer between Framer CMS and consumer applications, the team turned a single‑authoring system into a multi‑channel content hub. The approach delivers predictable performance, tighter security, and a clear path to scale horizontally. Future work could explore GraphQL façades for richer queries or Webhook‑driven sync to push the consistency window down to seconds.

Related resources

Comments

Loading comments...