← All workEntry 2 of 6
  • .NET
  • Adapter pattern
  • Azure Cache for Redis

Stayify Commerce Platform

Hotels run on many different systems. Stayify unifies them, so a hotel can build Experiences from rooms, tables and extras and sell them through one booking flow.

§1

The problem

An Experience can combine a room from the hotel's property-management system (Mews) with a table from its restaurant-booking system (Zenchef). Each system has its own data model, its own idea of availability, and in Zenchef's case almost no documentation. The platform had to generate Experiences from all of them, keep the results consistent, and stay fast, but asking every external system on every page view was slow and burned through API limits.

§2

How it works

  1. Mews, Zenchefeach speaks its own API
  2. Adaptersone per system
  3. Reconcileone common model
  4. Experiencesgenerated, bookable
Fig. 1  Each external system sits behind an adapter that translates it into one common model. Results from all systems are reconciled before they become a dynamic, bookable Experience.
  1. Guestsbrowse Experiences
  2. Stayify API.NET on Azure
  3. Redis cacheHangfire prefill
  4. Hotel systemswebhooks invalidate
Fig. 2  Availability is prefilled into Redis by a Hangfire job, so guests never wait on an external system. Webhooks, updates and bookings invalidate exactly the entries that changed.

Every integration implements the same adapter interface, so the rest of the platform never sees Mews or Zenchef directly, and adding another system means writing one adapter. Zenchef had little usable documentation, so much of that adapter came from reverse-engineering its API's real behaviour. I also refactored and remodelled core data models so the hot paths read less and compute less. Availability is cached in Azure Cache for Redis, kept warm by a Hangfire prefill job and invalidated by events (webhooks, updates and mutating operations). The platform runs on .NET with Azure Functions, CosmosDB and VNETs.

§3

Results

18 s → 80 msresponse time, after data remodelling, Redis caching and code optimisation

  • Mews and Zenchef integrated behind one adapter interface
  • Dynamic Experiences generated and reconciled across systems
  • Response times cut from 18 s to 80 ms (98% faster)
  • Far fewer calls to external systems, with data kept fresh by events instead of polling
§4

What I learned

  • When the docs are missing, the API's real behaviour is the documentation: reverse-engineer, then pin it down in an adapter
  • Adapters keep each system's quirks at the edge, so the core model stays clean
  • Data-model changes often beat code optimisation for speed
  • Cache invalidation is the real design problem: tie it to events, not timers