≡ Menu

In 2026, the “Microservices First” era has officially cooled.

Engineering teams have realized that for many use cases, distributed systems introduce more problems—latency, complex networking, and data inconsistency—than they solve.

The industry is shifting toward the Modular Monolith.

This isn’t just a “big ball of mud” renamed.

It’s a sophisticated architectural pattern where business logic is strictly isolated into independent modules, but the entire system runs in a single process.

For developers, this means simpler deployment and a streamlined infrastructure.

If you’re managing a database behind a private IP, the Modular Monolith allows you to secure that single connection point without the nightmare of managing VPC peering or Service Meshes for dozens of tiny apps.


🔬 The Deep Dive: Solving the “Shared Database” Dilemma

The most significant risk in a monolith is “Database Entanglement.” If every module can query every table, your code becomes a spiderweb. To build a true Modular Monolith in NestJS, you must enforce boundaries at the persistence layer.

1. Hard Boundaries: The “One Module, One Repository” Rule

Even though your modules share a single database connection (and likely a single schema), they should behave as if they don’t.

  • The Rule: OrdersModule must never inject the UserRepository.

  • The Solution: If Orders needs user data, it should request it via an internal QueryBus or an Event. This preserves the “Microservice Readiness” of the module.

2. Handling Transactions across Modules

In a distributed microservice, you’d need a Saga pattern. In a Monolith, we have the luxury of ACID transactions. However, we must pass the “Transaction Context” without leaking implementation details.

// orders.service.ts - Advanced Transaction Management
@Injectable()
export class OrdersService {
  constructor(
    private dataSource: DataSource, // Using TypeORM
    private eventEmitter: EventEmitter2
  ) {}

  async checkout(userId: string, cartItems: any[]) {
    return await this.dataSource.transaction(async (manager) => {
      // 1. Create the Order
      const order = await manager.save(Order, { userId, total: 100 });

      // 2. Emit a 'Critical' event and pass the manager
      // This allows the InventoryModule to decrement stock within the SAME transaction
      await this.eventEmitter.emitAsync('order.created.tx', {
        order,
        manager 
      });

      return order;
    });
  }
}

3. Avoiding Circular Dependencies

As a monolith grows, Users will eventually need Orders, and Orders will need Users. NestJS will throw a Circular dependency error.

How to fix it for real:

  • Shared Kernel: Move shared interfaces, DTOs, and Constants to a common directory that has zero dependencies on your feature modules.

  • Event-Driven Decoupling: Instead of Module A calling Module B, have Module A emit an event that Module B listens to. This breaks the link entirely.


💻 Code Example: The Decoupled Listener

Here is how the “other side” of that transaction looks.

Notice how the InventoryModule uses the passed EntityManager to stay within the same database transaction.

// inventory.listener.ts
@Injectable()
export class InventoryListener {
  @OnEvent('order.created.tx')
  async handleOrderCreated(payload: { order: any, manager: EntityManager }) {
    const { order, manager } = payload;

    // We use the 'manager' provided by the caller to ensure 
    // that if stock update fails, the Order creation also rolls back.
    await manager.update(Product, order.productId, {
      stock: () => "stock - 1"
    });
  }
}

🔒 Infrastructure: The Private IP Advantage

This architecture shines when it comes to security. By utilizing a Private IP for your database, you create a fortress.

  • Minimal Surface Area: Your database has no public endpoint. Only the NestJS process, living within your VPC, can talk to it.

  • Connection Efficiency: You manage a single connection pool. You don’t have to worry about 20 microservices each spinning up 10 connections and hitting the max_connections limit of your RDS or Postgres instance.


Scale Logic, Not Just Servers

Choosing a Modular Monolith isn’t about being “lazy”—it’s about being strategic.

It allows you to focus on your domain logic while keeping your infrastructure footprint small and secure.

When your “Orders” module eventually gets so much traffic that it needs its own dedicated CPU and memory, the migration is simple: move that folder to a new repo, swap the EventEmitter for a RabbitMQ or Kafka client, and you’ve officially moved to microservices.

Build for tomorrow, but ship today.

Useful links below:

Let me & my team build you a money making website/blog for your business https://bit.ly/tnrwebsite_service

Get Bluehost hosting for as little as $1.99/month (save 75%)…https://bit.ly/3C1fZd2

Best email marketing automation solution on the market! http://www.aweber.com/?373860

Build high converting sales funnels with a few simple clicks of your mouse! https://bit.ly/484YV29

Join my Patreon for one-on-one coaching and help with your coding…https://www.patreon.com/c/TyronneRatcliff

Buy me a coffee ☕️https://buymeacoffee.com/tyronneratcliff

 

{ 0 comments }

In the vast ocean of e-commerce, Shopify stands as a titan, empowering millions of entrepreneurs to bring their dreams to digital life.

While its user-friendly interface makes launching a store seem almost magical, a powerful, often unsung hero works tirelessly behind the scenes: Liquid.

Liquid is Shopify’s open-source templating language, crafted by Shopify’s co-founder Tobias Lütke.

Think of it as the intelligent translator between your store’s data (products, prices, customer info) and the beautiful HTML and CSS that your customers see in their browsers.

It’s the engine that powers your theme, dictating everything from how your product images are displayed to whether a discount message appears for a specific customer.

But what exactly is Liquid, and why should you, a Shopify store owner, care?

Let’s dive in.

The “No-Code” Myth: Why Understanding Liquid is Your Secret Weapon

Many Shopify owners pride themselves on being “no-code” entrepreneurs, and for good reason!

Shopify’s Online Store 2.0 (OS 2.0) themes offer incredible drag-and-drop functionality, allowing you to build stunning storefronts without touching a single line of code.

However, relying solely on pre-built sections and blocks can sometimes feel like trying to paint a masterpiece with only three colors. This is where a basic understanding of Liquid becomes your secret weapon. It allows you to:

  1. Go Beyond Theme Limitations: Want a specific product badge based on inventory levels? A custom message for customers in a particular country? Liquid makes it possible when your theme’s settings fall short.

  2. Optimize Performance: By understanding how Liquid renders content, you can identify and remove unnecessary code, leading to faster load times and improved Core Web Vitals.

  3. Troubleshoot with Confidence: Ever had an app leave behind broken code, or a theme update cause an unexpected glitch? Knowing a little Liquid helps you pinpoint the problem and often fix it yourself, saving you developer fees and downtime.

  4. Communicate Effectively with Developers: If you do hire a developer, being able to articulate your needs in Liquid terms ensures you get exactly what you want, faster and more efficiently.

  5. Future-Proof Your Store: As you scale, your needs become more unique. Liquid provides the flexibility to adapt your store without a complete rebuild.

How Liquid Works: A Glimpse Behind the Curtain

Liquid combines data with templates. Imagine you have a product in your Shopify admin with a title, price, and description. Liquid acts like a merge-field in a document:

  • It identifies specific placeholders (e.g., {{ product.title }}) in your theme files.

  • It fetches the corresponding data from your Shopify store.

  • It injects that data into the HTML, rendering the final output.

This process happens every time a customer loads a page on your store.

The Three Pillars of Liquid: Objects, Tags, and Filters

Liquid is built on three fundamental components:

  1. Objects ({{ ... }}): Objects are the data containers. They hold the information from your Shopify store that you want to display.

    • Example: {{ product.title }} displays the title of the current product.

    • Example: {{ shop.name }} displays your store’s name.

    • Common Objects: product, collection, customer, cart, shop, page, article, blog. Each object has various properties you can access.

  2. Tags ({% ... %}): Tags are the logic and control flow of Liquid. They tell your theme what to do, performing actions like conditionals, loops, and assignments.

    • Control Flow Tags:

      • {% if ... %} / {% else %} / {% endif %}: Used for conditional statements.

        Code snippet:

        {% if product.available %}
          <p>In Stock!</p>
        {% else %}
          <p>Sold Out</p>
        {% endif %}
        
      • {% for ... in ... %} / {% endfor %}: Used to loop through collections of items.

        Code snippet:

        {% for variant in product.variants %}
          <option value="{{ variant.id }}">{{ variant.title }}</option>
        {% endfor %}
        
    • Theme Tags: {% section 'header' %} (includes a section file), {% render 'snippet-name' %} (includes a snippet file).

    • Assignment Tags: {% assign my_variable = 'Hello' %} (creates a temporary variable).

  3. Filters (|): Filters modify the output of an object or variable. They are applied using the pipe (|) character.

    • Example: {{ product.price | money }} displays the product price formatted as currency (e.g., “$29.99”).

    • Example: {{ product.description | truncate: 100 }} shortens the description to 100 characters.

    • Common Filters: date, upcase, downcase, strip_html, plus, minus, times, divided_by, url_encode, img_url. Filters are incredibly powerful for formatting data for display or for use in other parts of your code.

Where Do You Find Liquid in Your Shopify Store?

You’ll encounter Liquid primarily in your theme’s files. To access these, navigate to Online Store > Themes > Actions > Edit code in your Shopify admin.

Key directories where Liquid lives:

  • sections/: Contains modular blocks of content (e.g., header.liquid, footer.liquid, product-template.liquid). OS 2.0 themes are heavily built on sections.

  • snippets/: Smaller, reusable pieces of code that can be included in sections or other templates (e.g., product-card.liquid, icon-svg.liquid).

  • templates/: Core page layouts for different types of content (e.g., product.liquid, collection.liquid, page.liquid, cart.liquid).

  • layout/theme.liquid: The master file that wraps around all other templates, containing global elements like the <html>, <head>, and <body> tags, and often calls for your header and footer sections.

Practical Applications: Small Tweaks, Big Impact

Even without becoming a full-blown developer, a few Liquid tricks can significantly enhance your store:

  • Custom Product Badges: Display “New Arrival” if product.created_at is within the last 30 days, or “Low Stock!” if product.variants.first.inventory_quantity < 5.

  • Conditional Content: Show a special promotion banner only to logged-in customers ({% if customer %}).

  • Dynamic Descriptions: Automatically insert the current year into your copyright notice (Copyright {{ 'now' | date: "%Y" }}).

  • Optimized Image URLs: Use filters like {{ image | img_url: 'medium' }} to ensure images load at appropriate sizes for different devices.

  • A/B Testing with Tags: Assign customers a tag (e.g., test-group-A) and use Liquid to show them different content or pricing.

Embracing the Power of Liquid

In the dynamic world of e-commerce, staying ahead means leveraging every tool at your disposal.

While Shopify makes it easy to get started, understanding Liquid elevates your store from a standard template to a truly bespoke and optimized online presence.

It empowers you to implement subtle yet impactful changes, troubleshoot issues with confidence, and ultimately, create a more engaging and high-performing shopping experience for your customers.

So, don’t shy away from that “Edit code” button.

Start small, experiment, and you’ll quickly discover the immense power that Liquid holds, transforming you from a mere store owner into a true digital artisan.

Useful links below:

Let me & my team build you a money making website/blog for your business https://bit.ly/tnrwebsite_service

Get Bluehost hosting for as little as $1.99/month (save 75%)…https://bit.ly/3C1fZd2

Best email marketing automation solution on the market! http://www.aweber.com/?373860

Build high converting sales funnels with a few simple clicks of your mouse! https://bit.ly/484YV29

Join my Patreon for one-on-one coaching and help with your coding…https://www.patreon.com/c/TyronneRatcliff

Buy me a coffee ☕️https://buymeacoffee.com/tyronneratcliff

{ 0 comments }