Skip to content

Setting up Glossaries

Glossaries are files that contain lists of terms, their definitions and other attributes. You can have as many glossary files as you like in your repository.

For Contextive to find a glossary file, it must match the pattern *.glossary.yml. You can name the prefix whatever you like, so project.glossary.yml and module.glossary.yml are both valid filenames, but module-glossary.yml is not.

When setting up a glossary file, there are two things to do:

  1. Define a bounded context in the header of the glossary - see Bounded Contexts
  2. Decide where to put the glossary file - this affects which files are supported by its terminology - see Glossary Location

Bounded Contexts

In Domain-Driven Design, a Bounded Context is a logical boundary around a model of some portion of the domain. It’s quite common for different Bounded Contexts to evolve their own unique ‘languages’ or ‘dialects’, so it is helpful to keep them in separate glossary files.

A Simple Bounded Context

The top level of the *.glossary.yml file is a list of bounded contexts. The key in the yml file is contexts. A file with a single context looks like:

shipping.glossary.yml
contexts:
- name: Shipping
terms:
- name: Order
definition: A set of parcels with a common delivery destination.
- % other terms %
...

Shipping Context Headers

The name field is optional, but generally recommended.

Defining a Domain Vision Statement

domainVisionStatement is an optional field that allows you to express the purpose of the context.

shipping.glossary.yml
contexts:
- name: Shipping
domainVisionStatement: To manage the shipping of orders to customers.
terms:
- name: Order
definition: A set of parcels with a common delivery destination.
- % other terms %
...

Shipping Context Headers

Context Metadata

Contexts can have a meta key which allows defining an arbitrary set of key:value pairs. The value must be a string, and they are rendered exactly as supplied with a space between them.

Both the key and the value support markdown, which can allow for hyperlinks out to more thorough documentation, e.g.:

shipping.glossary.yml
contexts:
- name: Shipping
domainVisionStatement: To manage the shipping of orders to customers.
meta:
"👥 Owner:": "[Team A](https://corporate.wiki/teams/TeamA)"
"🌐 Ref:": "[Cargo Canonical Reference](https://corporate.wiki/glossary/shipping)"
terms:
- name: Order
definition: A set of parcels with a common delivery destination.
- % other terms %
...

Shipping Context Headers

No Context definition

All three fields - name, domainVisionStatement and meta are optional. If none are undefined, the context can be as simple as:

shipping.glossary.yml
contexts:
- terms:
- name: Order
definition: A set of parcels with a common delivery destination.
- % other terms %
...

Which would just show the term definition:

Shipping Context Without Headers

See defining terminology for details on defining terms.

Glossary File Template

When getting started, it could be helpful to copy the default glossary file template which contains all possible fields and is used to define the terms used in the glossary file itself.

It can be used as a starting point to edit and amend to incorporate your contexts and define your terms.

Glossary Location

The following sections explore common patterns for where to place your glossary files.

Terms relevant for the whole repository

If the terms in a file are useful for all files in the repository, then you should put the glossary file in the root.

  • Directoryrepository
    • projectName.glossary.yml <— a glossary for the whole repository
    • README.md
    • Directoryfrontend
      • Directorycomponents
        • SubmitOrder.ts
    • Directorybackend
      • Directorydomain
        • Order.cs

In the example above, if projectName.glossary.yml contains a definition for the term Order, then that definition will be used when editing README.md, frontend\Components\SubmitOrder.ts and backend\domain\Order.cs.

Different terms relevant in different repositories

This is the same as the previous pattern, but is described to be explicit for teams who are using multiple repositories.

For this approach to work, each repository must deal with different domain concepts so that the terms useful in one repository are irrelevant in the others, and visa versa.

This pattern is particularly useful if each repository contains all the code associated with a Bounded Context.

  • Directoryshipping-repository
    • shipping.glossary.yml <— a glossary only for shipping
    • Directorysrc
      • Order.cs
  • Directorypayments-repository
    • payments.glossary.yml <— a glossary only for payments
    • Directorysrc
      • Order.cs

In this case, shipping.glossary.yml might define Order as A set of parcels with a common delivery destination.. This definition will be shown when working on in the shipping repository.

payments.glossary.yml might define Order as An amount to be charged to the customer and the payment method to charge.. This definition will be shown when working in the payments repository.

Terms relevant only in a subfolder of the repository

If the terms in a file are useful only in a subfolder, put the glossary file in the top-most folder that encompasses those relevant files.

For example, if you are building a ‘modular monolith’ in a monorepo, you might have your modules in separate folders, in which case you should put definitions relevant to each module in that module’s folder, like so:

  • Directoryrepository
    • README.md
    • Directoryshipping
      • shipping.glossary.yml <— a glossary only for shipping
      • Directorysrc
        • Order.cs
    • Directorypayments
      • payments.glossary.yml <— a glossary only for payments
      • Directorysrc
        • Order.cs

Assuming the same definitions as before, where shipping.glossary.yml defines Order as A set of parcels with a common delivery destination. and payments.glossary.yml defines Order as An amount to be charged to the customer and the payment method to charge., then:

  • When working on /shipping/src/Order.cs, hovering over the word Order will show A set of parcels with a common delivery destination.
  • When working on /payments/src/Order.cs, hovering over the word Order will show An amount to be charged to the customer and the payment method to charge.

This pattern is particularly useful if each module in your modular monolith contains all the code associated with a Bounded Context.

Terms defined in an external data source

Some organisations already have their terms defined in an existing dataset and do not want to maintain them separately in a repository.

For this purpose, you can create a glossary that imports from a remote URL. The contents of the remote URL are then treated as though they were available at the position in the folder structure of the importing file.

  • Directoryrepository
    • README.md
    • Directoryshipping
      • shipping.glossary.yml <— will import from a remote URL
      • Directorysrc
        • Order.cs
    • Directorypayments
      • payments.glossary.yml
      • Directorysrc
        • Order.cs
shipping/shipping.glossary.yml
imports:
- "https://your.domain/path/to/shipping.glossary.yml"

With this configuration, any terminology contained in the file located at https://your.domain/path/to/shipping.glossary.yml will be made available as though it had been defined in shipping/shipping.glossary.yml.

Multiple glossary files may be imported into the same location by defining a list of imports.

shipping/shipping.glossary.yml
imports:
- "https://your.domain/path/to/shipping.glossary.yml"
- "https://your.domain/path/to/other.glossary.yml"

Terms relevant in multiple folder locations

Sometimes even though bounded contexts have different languages and are neatly separated, it’s helpful to have access to terms from another context in some parts of the code - consider code that deals with integration between the contexts.

In this case, the integration folder can contain a glossary file that imports another glossary file from a local absolute or relative path:

  • Directoryrepository
    • README.md
    • Directoryshipping
      • shipping.glossary.yml
      • Directorysrc
        • Order.cs
        • DirectoryantiCorruptionLayer
          • payments-import.glossary.yml <— will import from the payments glossary
          • HandleOrderPaymentReceived.cs
    • Directorypayments
      • payments.glossary.yml
      • Directorysrc
        • Order.cs
shipping/src/antiCorruptionLayer/payments-import.glossary.yml
imports:
- "../../../payments/payments.glossary.yml"

This will ensure that when working on HandleOrderPaymentReceived.cs all the terms defined in shipping.glossary.yml AND payments.glossary.yml will be available, with clear delineation between contexts, even when the same word has different meanings in each context:

Shipping Context AntiCorruption Layer with Imported Payments Terminology

When working on shipping/src/Order.cs, only the definition from shipping.glossary.yml will be shown, and when working on payments/src/Order.cs only the definition from payments.glossary.yml will be shown.

Combining Imports with Terminology

A glossary file can contain a list of imports as well as contexts and terms - they will all be made available when working in the folder, e.g.:

shipping/src/antiCorruptionLayer/payments-import.glossary.yml
imports:
- "../../../payments/payments.glossary.yml"
contexts:
- name: Shipping Anti-corruption Layer
terms:
- name: Shipping Fee

In this case the Shipping Fee is a term that is relevant when integrating between payments and shipping, but note that it is part of a separate Context - importing a file does not merge the contexts, rather, it acts as though all contexts were defined in the same file.

Terms relevant across multiple repositories

Some organisations have adopted a distributed repository configuration, where small services (microservices, or cloud FAAS functions) are each located in their own repositories. Often in these cases, the code in these repositories share a domain language.

If you have multiple repositories that would benefit from access to the same terms, then it’s recommended to define the terms in one repository and publish them to a publicly accessibly URL.

You can then use the imports feature in the other repositories and provide the URL that you have publishd your glossary file to.

Multi-root workspaces

Some IDEs (e.g. VsCode) support multi-root workspaces.

Contextive will use glossary files based on their location on disk relative to the files that are being edited and will not consider the multi-root structure.

However, it will only discover glossaries by searching from each of the roots, so depending on the disk layout of the roots, terms may or may not be used across multiple roots.

In this approach, it’s recommended to use something like Terms relevant only in a subfolder of the repository, where each subfolder is ‘root’ in the multi-root workspace.

Multiple Bounded Contexts in a Glossary File

Early versions of Contextive used a single glossary file with all contexts in it, and for backwards compatibility reasons, this is still supported.

To scope the context to a particular portion of the repository, as described in Terms relevant only in a subfolder of the repository, then each context can have a list of path globs supplied and the terms in that context will only be shown for files that match the path glob.

For example, to achieve the same outcome, you could have a structure like:

  • Directoryrepository
    • project.glossary.yml a glossary with all contexts and terms
    • README.md
    • Directoryshipping
      • Directorysrc
        • Order.cs
    • Directorypayments
      • Directorysrc
        • Order.cs

And the contexts could be defined like so:

project.glossary.yml
contexts:
- name: Shipping
domainVisionStatement: To manage the shipping of orders to customers.
paths:
- shipping
terms:
- % list of terms in the shipping context
- name: Payments
domainVisionStatement: To manage handling payments, refunds & financial reconciliations for orders.
paths:
- payments
terms:
- * list of terms in the payments context