0

Modularity concepts

For users testing modularity v2 in Ninox 3.17 beta on Private Cloud

ℹ️ Note: This article explains the ideal, conceptual model of Ninox modularity. It isn't a specification of modularity v2, which is currently in beta; names, workflows, and availability may differ. For the latest implementation details and step-by-step guidance, refer to the FAQ/quick start and glossary.

1. Understanding the concept

Modularity is the practice of building software as a collection of independent, interoperable units (modules). In Ninox, a module is a self-contained database that shares only selected data and logic through a designated interface. Since all external access goes through this interface, you can reuse, replace, or update the module without exposing its internal setup.

Benefits of modularity

  • Isolation: Schema changes and bugs stay inside the module that caused them.
  • Reusability: One module can serve many solutions without copy‑pasting logic.
  • Updatability: You can release new versions without breaking consumer databases.

2. Best practices

At first, deliberately hiding tables and fields may feel limiting. Over time, lean interfaces make your solution safer to maintain and easier to evolve.

Best practices for easier maintainability and development

  • Loose coupling: Expose only what another module truly needs. Fewer exposed fields mean fewer places where changes have an impact.
  • Separation of concerns: Give each module a single, well‑defined responsibility.
  • Domain modeling: Design tables around real‑world entities inside that domain.

3. Key properties and practical impact

At a glance, modularity in Ninox is about clear contracts and controlled sharing: a module keeps its internal data and logic private and shows other apps only what its interface exposes. internals to itself and shows other apps only what its interface exposes. This approach retains encapsulation while allowing teams to compose larger solutions. The interface is the public contract—tables and fields you've chosen to expose—so consumers never depend on private tables, layout fields, or scripts.

These six key properties highlight how the design of modularity impacts practical, every-day use:

  • Interoperability comes from stable identifiers. Every exposed table and field is defined on the interface with a system ID and a public name. Authors keep their own internal names for clarity, while consumers see only the public name. Because the public name maps to a hidden ID, you can rename labels without breaking connections. The interface ID itself is the API-level identifier for the contract, so changing it creates a new interface that consumers must update to.
  • Replaceability means you can swap modules with minimal disruption: if two modules share the same interface identifier and exposed element IDs, a consumer can swap to the newer or alternative provider without breaking existing connections. This is exactly what loose coupling optimizes for—easier updates, reuse, and replacement over time.
  • Updatability is handled by versioning and a safe upgrade path. Saving changes on the interface automatically bumps the version. Consumers can continue working on the previous version and decide when to reconnect to the latest one. If a link is broken, external tables remain in the consumer database with all data intact but stop syncing until consumers reconnect.
  • Security and access control are enforced at the interface. Read access is the default for anything you expose; write access must be granted explicitly to consumers. The provider always retains write access, and we recommend granting write access sparingly.
  • Composability means you can add multiple modules to the same workspace—each in its own database with its own interface—and layer them using patterns like core/extension or shared references.
  • Distribution is the process of packaging or publishing a module (including its interface) so it can be shared or imported across workspaces.

✅ Tip: When using modularity:

  • Expose only the data fields consumers truly need.
  • Rely on public names and IDs for stability.
  • Plan changes as interface versions.
  • Prefer read access unless a workflow requires writes.
  • Design modules so they can be composed or replaced without touching internal tables and scripts.

4. Layering modules: A mental model

Think of modules like layers of an onion. A core business module (for example, "HR") sits at the center, while complementary modules (for example, "Time tracking") surround it. If "Time tracking" only needs hours, keep it separate; if payroll or absence planning requires deeper, shared data, keep those tables inside "HR." The point is to let data flow where it must—no further.

5. Modular vs. non‑modular databases

Instead of blending everything into one big app, a modular solution draws clear boundaries and connects them through an interface.

  • In a regular (non-modular) database, tables share data via ad‑hoc scripts and direct references. Renaming a field or table rarely affects other apps because everything lives in one place, but it ties concerns together and complicates testing and replacement.
  • In a modular database, the provider exposes selected tables and fields through an interface. Consumers receive external tables that mirror those exposed parts and stay in sync while connected. Because the interface is the contract, providers can safely change internal names and structure, while consumers rely on stable IDs and public names.

6. How interfaces shape change—versioning

Interfaces make change explicit. When you adjust what the interface exposes and then save, Ninox creates a new interface version. Consumers continue to work on the previous version and can upgrade when ready.

✅ Tip: Treat interface changes as product releases: communicate intent, test with a consumer database, and plan for consumers to reconnect.

What to keep in mind

  • Changing internal (non‑exposed) fields doesn't affect the interface.
  • Public names can be refined without breaking consumers because IDs remain stable.
  • The interface ID is part of the contract; changing it creates a new interface that requires consumers to update.

7. Data sharing and synchronization—what to expect

When a consumer connects to a provider's interface, Ninox creates external tables in the consumer database—one per exposed table—and immediately populates them with the provider's current records.

While connected:

  • Read access: Updates flow from provider to consumer; edits in the consumer database don't change the provider.
  • Write access: Updates flow both ways; consumer database edits are applied to the provider.

If the interface is removed or a database is moved or deleted, the former external tables remain in the consumer database as regular tables. They stop syncing, but the data isn't lost.

8. Naming—IDs, internal and public names

Clear naming conventions benefit both authors and consumers.

  • Internal table names or field names keep the schema readable for authors and can be changed at any time.
  • Public table names or table names are what consumers see in the UI and formulas. You can refine these without breaking anything because the underlying system IDs remain the same.
  • Interface IDs identify the interface itself for both authors and consumers. Treat the ID as a versioned API label and use a human-readable name.

9. Design guidelines

Good interfaces are intentionally lean and audience‑aware.

  • Expose only what's needed. Keep dependencies shallow by sharing the minimum data required between modules.
  • Align modules with business capabilities. For example, create a "Recruiting" module rather than an overly specific one like "Applicant address."
  • Customize public fields to the audience. Partners may need broader sets; internal teams often need only what their workflow requires.

10. Common design patterns

Use these patterns to keep modules simple yet effective:

  • Core and extension: Provide a mandatory base with optional add‑ons. Example: "HR core" with a "Time & attendance pack."

  • Shared reference: Centralize lookup data that multiple modules rely on. Example: A country‑codes module consumed by "Billing," "Logistics," and "CRM."

  • Facade: Hide complexity behind a slim, read-only table that aggregates key metrics from several tables. Example: A project dashboard that returns KPIs.

11. Where to go next

  • For step‑by‑step flows for module authors and consumers, visit the FAQ and quick start.
  • For precise definitions of roles, fields, names, and permissions, refer to the glossary.

Reply

null