Interfaces
A module can adopt a public interface by matching interface rules in tach.toml
.
How does it work?
When Tach is checking imports from a module with a public interface, it will verify that the import matches one of the expose
patterns.
This prevents other modules from becoming coupled to implementation details, and makes future changes easier.
Example
Given modules called ‘core’ and ‘domain’, we may have tach.toml
contents like this:
Then, in domain.py
, we may have:
This import would fail tach check
with the following error:
In this case, there is a public interface defined in tach.toml
which includes a service method to use instead.
tach check
will now pass!
Interface visibility
Interfaces can specify visibility
, similar to modules.
This allows ‘splitting’ the interface, usually to support a detailed/sensitive interface for some consumers while maintaining a minimal interface by default.
Example
In the configuration shown above, the api
module exposes only read_data
to most consumers,
while also providing write_data
through an interface visible only to admin.controller
.
You may attach an arbitrary number of interfaces to the same module, with varying visibility
.
Example: Exclusive interface
It is also possible to mark an interface with exclusive: true
.
When an interface is exclusive
, it will override all other matching interfaces for the module,
which is only relevant when using visibility
as shown above.
Using the example above:
By marking the write_data
interface as exclusive, we are saying that admin.controller
should exclusively use api
through that interface (e.g. write_data
).