-
Couldn't load subscription status.
- Fork 7
ADR 009 cardano api exports convention
✅ Accepted 2025-02-21
The current module structure of cardano-api is very ad-hoc.
It is not clearly defined where modules should be placed and how to be exported.
This ADR aims to standardise this process.
Each top level export should export distinct symbols.
This may depend on the case, for example: Cardano.Api.Byron symbols which are still in use in current eras, can be reexported through Cardano.Api.
-
Cardano.Api- everything domain related for the currently used and upcoming eras -
Cardano.Api.<F>, where<F>represents a feature. An aggregate module providing one of corecardano-apifunctionalities. The name has to be a singular noun. The purpose of this export is to provide users a more granular control of imports if they don't want to import a catch-allCardano.Apimodule. For example:Cardano.Api.AddressCardano.Api.BlockCardano.Api.CertificateCardano.Api.EonCardano.Api.GenesisCardano.Api.GovernanceCardano.Api.IPCCardano.Api.KeyCardano.Api.LedgerStateCardano.Api.QueryCardano.Api.SerialisationCardano.Api.Tx
The following rules apply:
-
The modules should not be very granular, only related to a particular feature set. For example
-
Cardano.Api.Governance.Actions.ProposalProcedureshould not be a top level export and should be exported throughCardano.Api.Governance. -
Cardano.Api.LedgerEventsshould not be a top level export and should be exported throughCardano.Api.LedgerState.
-
-
The module should be reexported through
Cardano.Api. This makes usingcardano-apieasier, by not forcing users to decide what to import, and allowing them to just simply writeimport Cardano.Api.
-
Cardano.Api.Byron- everything for the obsoleted Byron era -
Cardano.Api.Compatible- everything for the older eras. The purpose of this module to provide a limited backwards compatibility for eras not in use on Cardano mainnet. This is meant only for supporting of tests which hardfork through eras.For both
Cardano.Api.ByronandCardano.Api.Compatiblethe following rules apply:- Any symbol from previous era, not in use in current era, should be exported through the respective module for older eras.
- Any symbol from previous era and still in use in the current era, should be exported through
Cardano.Apiand additionally throughCardano.Api.(Byron|Compatible).
-
Cardano.Api.Experimental- a transient module for implementing new not yet stabilised APIs. Not meant to be used bycardan-apiusers directly. -
Cardano.Api.<U>utility module, where<U>represents a utilities set. For exampleCardano.Api.Pretty,Cardano.Api.Monad.Error.-
Reexports from upstream libraries like consensus, network or ledger, also fall into this category e.g.
Cardano.Api.Ledger. -
Modules which are exposing general purpose classes and functions should go also into a separate module, and they don't need to be reexported through
Cardano.Api. For exampleCardano.Api.Tx.UTxO- a wrapper type, with functions common to maps which would clash with other map data structures. A good example of this pattern from Hackage isData.Aeson.KeyMap.
In principle, those should not be reexported from
Cardano.Api, because they would pollute symbol namespace, and are not required for usingcardano-apicore features but can be useful for the advanced users. In certain situations, parts of those modules can be reexported fromCardano.Api, to provide more seamless experience of using the mainCardano.Apimodule. -
Any other modules not meant to be a top level export, should be placed inside Cardano.Api.Internal or Cardano.Api.<X>.Internal and be reexported through a suitable top level module.
In general internal modules shouldn't be exposed in cabal package, but it may be necessary for using them from other components in cardano-api, like tests.
This however depends on the specific use case.
Internal in the module name should indicate that the module isn't really meant to be used directly, and users can expect more frequent breakage when relying on it.
-
Cardano.Api.<X>.InternalorCardano.Api.Internal.<X>or should contain everything related to the domain<X>.- If
Cardano.Api.<X>is a top level export, internal functions should go toCardano.Api.<X>.Internal(e.g.Cardano.Api.Address.Internal), otherwise - if there's no
Cardano.Api.<X>top level export, internal functions should go toCardano.Api.Internal.<X>(e.g.Cardano.Api.Internal.Orphans).
A good example from Hackage how to nest
Internalmodules istextpackage. - If
Acceptance of ADR will require rename of almost all cardano-api modules which will be a breaking change.
The cardano-node wiki has moved. Please go to (https://github.com/input-output-hk/cardano-node-wiki/wiki) and look for the page there.