github.com/cosmos/cosmos-sdk@v0.50.10/docs/architecture/adr-023-protobuf-naming.md (about)

     1  # ADR 023: Protocol Buffer Naming and Versioning Conventions
     2  
     3  ## Changelog
     4  
     5  * 2020 April 27: Initial Draft
     6  * 2020 August 5: Update guidelines
     7  
     8  ## Status
     9  
    10  Accepted
    11  
    12  ## Context
    13  
    14  Protocol Buffers provide a basic [style guide](https://developers.google.com/protocol-buffers/docs/style)
    15  and [Buf](https://buf.build/docs/style-guide) builds upon that. To the
    16  extent possible, we want to follow industry accepted guidelines and wisdom for
    17  the effective usage of protobuf, deviating from those only when there is clear
    18  rationale for our use case.
    19  
    20  ### Adoption of `Any`
    21  
    22  The adoption of `google.protobuf.Any` as the recommended approach for encoding
    23  interface types (as opposed to `oneof`) makes package naming a central part
    24  of the encoding as fully-qualified message names now appear in encoded
    25  messages.
    26  
    27  ### Current Directory Organization
    28  
    29  Thus far we have mostly followed [Buf's](https://buf.build) [DEFAULT](https://buf.build/docs/lint-checkers#default)
    30  recommendations, with the minor deviation of disabling [`PACKAGE_DIRECTORY_MATCH`](https://buf.build/docs/lint-checkers#file_layout)
    31  which although being convenient for developing code comes with the warning
    32  from Buf that:
    33  
    34  > you will have a very bad time with many Protobuf plugins across various languages if you do not do this
    35  
    36  ### Adoption of gRPC Queries
    37  
    38  In [ADR 021](adr-021-protobuf-query-encoding.md), gRPC was adopted for Protobuf
    39  native queries. The full gRPC service path thus becomes a key part of ABCI query
    40  path. In the future, gRPC queries may be allowed from within persistent scripts
    41  by technologies such as CosmWasm and these query routes would be stored within
    42  script binaries.
    43  
    44  ## Decision
    45  
    46  The goal of this ADR is to provide thoughtful naming conventions that:
    47  
    48  * encourage a good user experience for when users interact directly with
    49  .proto files and fully-qualified protobuf names
    50  * balance conciseness against the possibility of either over-optimizing (making
    51  names too short and cryptic) or under-optimizing (just accepting bloated names
    52  with lots of redundant information)
    53  
    54  These guidelines are meant to act as a style guide for both the Cosmos SDK and
    55  third-party modules.
    56  
    57  As a starting point, we should adopt all of the [DEFAULT](https://buf.build/docs/lint-checkers#default)
    58  checkers in [Buf's](https://buf.build) including [`PACKAGE_DIRECTORY_MATCH`](https://buf.build/docs/lint-checkers#file_layout),
    59  except:
    60  
    61  * [PACKAGE_VERSION_SUFFIX](https://buf.build/docs/lint-checkers#package_version_suffix)
    62  * [SERVICE_SUFFIX](https://buf.build/docs/lint-checkers#service_suffix)
    63  
    64  Further guidelines to be described below.
    65  
    66  ### Principles
    67  
    68  #### Concise and Descriptive Names
    69  
    70  Names should be descriptive enough to convey their meaning and distinguish
    71  them from other names.
    72  
    73  Given that we are using fully-qualifed names within
    74  `google.protobuf.Any` as well as within gRPC query routes, we should aim to
    75  keep names concise, without going overboard. The general rule of thumb should
    76  be if a shorter name would convey more or else the same thing, pick the shorter
    77  name.
    78  
    79  For instance, `cosmos.bank.MsgSend` (19 bytes) conveys roughly the same information
    80  as `cosmos_sdk.x.bank.v1.MsgSend` (28 bytes) but is more concise.
    81  
    82  Such conciseness makes names both more pleasant to work with and take up less
    83  space within transactions and on the wire.
    84  
    85  We should also resist the temptation to over-optimize, by making names
    86  cryptically short with abbreviations. For instance, we shouldn't try to
    87  reduce `cosmos.bank.MsgSend` to `csm.bk.MSnd` just to save a few bytes.
    88  
    89  The goal is to make names **_concise but not cryptic_**.
    90  
    91  #### Names are for Clients First
    92  
    93  Package and type names should be chosen for the benefit of users, not
    94  necessarily because of legacy concerns related to the go code-base.
    95  
    96  #### Plan for Longevity
    97  
    98  In the interests of long-term support, we should plan on the names we do
    99  choose to be in usage for a long time, so now is the opportunity to make
   100  the best choices for the future.
   101  
   102  ### Versioning
   103  
   104  #### Guidelines on Stable Package Versions
   105  
   106  In general, schema evolution is the way to update protobuf schemas. That means that new fields,
   107  messages, and RPC methods are _added_ to existing schemas and old fields, messages and RPC methods
   108  are maintained as long as possible.
   109  
   110  Breaking things is often unacceptable in a blockchain scenario. For instance, immutable smart contracts
   111  may depend on certain data schemas on the host chain. If the host chain breaks those schemas, the smart
   112  contract may be irreparably broken. Even when things can be fixed (for instance in client software),
   113  this often comes at a high cost.
   114  
   115  Instead of breaking things, we should make every effort to evolve schemas rather than just breaking them.
   116  [Buf](https://buf.build) breaking change detection should be used on all stable (non-alpha or beta) packages
   117  to prevent such breakage.
   118  
   119  With that in mind, different stable versions (i.e. `v1` or `v2`) of a package should more or less be considered
   120  different packages and this should be last resort approach for upgrading protobuf schemas. Scenarios where creating
   121  a `v2` may make sense are:
   122  
   123  * we want to create a new module with similar functionality to an existing module and adding `v2` is the most natural
   124  way to do this. In that case, there are really just two different, but similar modules with different APIs.
   125  * we want to add a new revamped API for an existing module and it's just too cumbersome to add it to the existing package,
   126  so putting it in `v2` is cleaner for users. In this case, care should be made to not deprecate support for
   127  `v1` if it is actively used in immutable smart contracts.
   128  
   129  #### Guidelines on unstable (alpha and beta) package versions
   130  
   131  The following guidelines are recommended for marking packages as alpha or beta:
   132  
   133  * marking something as `alpha` or `beta` should be a last resort and just putting something in the
   134  stable package (i.e. `v1` or `v2`) should be preferred
   135  * a package _should_ be marked as `alpha` _if and only if_ there are active discussions to remove
   136  or significantly alter the package in the near future
   137  * a package _should_ be marked as `beta` _if and only if_ there is an active discussion to
   138  significantly refactor/rework the functionality in the near future but not remove it
   139  * modules _can and should_ have types in both stable (i.e. `v1` or `v2`) and unstable (`alpha` or `beta`) packages.
   140  
   141  _`alpha` and `beta` should not be used to avoid responsibility for maintaining compatibility._
   142  Whenever code is released into the wild, especially on a blockchain, there is a high cost to changing things. In some
   143  cases, for instance with immutable smart contracts, a breaking change may be impossible to fix.
   144  
   145  When marking something as `alpha` or `beta`, maintainers should ask the questions:
   146  
   147  * what is the cost of asking others to change their code vs the benefit of us maintaining the optionality to change it?
   148  * what is the plan for moving this to `v1` and how will that affect users?
   149  
   150  `alpha` or `beta` should really be used to communicate "changes are planned".
   151  
   152  As a case study, gRPC reflection is in the package `grpc.reflection.v1alpha`. It hasn't been changed since
   153  2017 and it is now used in other widely used software like gRPCurl. Some folks probably use it in production services
   154  and so if they actually went and changed the package to `grpc.reflection.v1`, some software would break and
   155  they probably don't want to do that... So now the `v1alpha` package is more or less the de-facto `v1`. Let's not do that.
   156  
   157  The following are guidelines for working with non-stable packages:
   158  
   159  * [Buf's recommended version suffix](https://buf.build/docs/lint-checkers#package_version_suffix)
   160  (ex. `v1alpha1`) _should_ be used for non-stable packages
   161  * non-stable packages should generally be excluded from breaking change detection
   162  * immutable smart contract modules (i.e. CosmWasm) _should_ block smart contracts/persistent
   163  scripts from interacting with `alpha`/`beta` packages
   164  
   165  #### Omit v1 suffix
   166  
   167  Instead of using [Buf's recommended version suffix](https://buf.build/docs/lint-checkers#package_version_suffix),
   168  we can omit `v1` for packages that don't actually have a second version. This
   169  allows for more concise names for common use cases like `cosmos.bank.Send`.
   170  Packages that do have a second or third version can indicate that with `.v2`
   171  or `.v3`.
   172  
   173  ### Package Naming
   174  
   175  #### Adopt a short, unique top-level package name
   176  
   177  Top-level packages should adopt a short name that is known to not collide with
   178  other names in common usage within the Cosmos ecosystem. In the near future, a
   179  registry should be created to reserve and index top-level package names used
   180  within the Cosmos ecosystem. Because the Cosmos SDK is intended to provide
   181  the top-level types for the Cosmos project, the top-level package name `cosmos`
   182  is recommended for usage within the Cosmos SDK instead of the longer `cosmos_sdk`.
   183  [ICS](https://github.com/cosmos/ics) specifications could consider a
   184  short top-level package like `ics23` based upon the standard number.
   185  
   186  #### Limit sub-package depth
   187  
   188  Sub-package depth should be increased with caution. Generally a single
   189  sub-package is needed for a module or a library. Even though `x` or `modules`
   190  is used in source code to denote modules, this is often unnecessary for .proto
   191  files as modules are the primary thing sub-packages are used for. Only items which
   192  are known to be used infrequently should have deep sub-package depths.
   193  
   194  For the Cosmos SDK, it is recommended that we simply write `cosmos.bank`,
   195  `cosmos.gov`, etc. rather than `cosmos.x.bank`. In practice, most non-module
   196  types can go straight in the `cosmos` package or we can introduce a
   197  `cosmos.base` package if needed. Note that this naming _will not_ change
   198  go package names, i.e. the `cosmos.bank` protobuf package will still live in
   199  `x/bank`.
   200  
   201  ### Message Naming
   202  
   203  Message type names should be as concise possible without losing clarity. `sdk.Msg`
   204  types which are used in transactions will retain the `Msg` prefix as that provides
   205  helpful context.
   206  
   207  ### Service and RPC Naming
   208  
   209  [ADR 021](adr-021-protobuf-query-encoding.md) specifies that modules should
   210  implement a gRPC query service. We should consider the principle of conciseness
   211  for query service and RPC names as these may be called from persistent script
   212  modules such as CosmWasm. Also, users may use these query paths from tools like
   213  [gRPCurl](https://github.com/fullstorydev/grpcurl). As an example, we can shorten
   214  `/cosmos_sdk.x.bank.v1.QueryService/QueryBalance` to
   215  `/cosmos.bank.Query/Balance` without losing much useful information.
   216  
   217  RPC request and response types _should_ follow the `ServiceNameMethodNameRequest`/
   218  `ServiceNameMethodNameResponse` naming convention. i.e. for an RPC method named `Balance`
   219  on the `Query` service, the request and response types would be `QueryBalanceRequest`
   220  and `QueryBalanceResponse`. This will be more self-explanatory than `BalanceRequest`
   221  and `BalanceResponse`.
   222  
   223  #### Use just `Query` for the query service
   224  
   225  Instead of [Buf's default service suffix recommendation](https://github.com/cosmos/cosmos-sdk/pull/6033),
   226  we should simply use the shorter `Query` for query services.
   227  
   228  For other types of gRPC services, we should consider sticking with Buf's
   229  default recommendation.
   230  
   231  #### Omit `Get` and `Query` from query service RPC names
   232  
   233  `Get` and `Query` should be omitted from `Query` service names because they are
   234  redundant in the fully-qualified name. For instance, `/cosmos.bank.Query/QueryBalance`
   235  just says `Query` twice without any new information.
   236  
   237  ## Future Improvements
   238  
   239  A registry of top-level package names should be created to coordinate naming
   240  across the ecosystem, prevent collisions, and also help developers discover
   241  useful schemas. A simple starting point would be a git repository with
   242  community-based governance.
   243  
   244  ## Consequences
   245  
   246  ### Positive
   247  
   248  * names will be more concise and easier to read and type
   249  * all transactions using `Any` will be at shorter (`_sdk.x` and `.v1` will be removed)
   250  * `.proto` file imports will be more standard (without `"third_party/proto"` in
   251  the path)
   252  * code generation will be easier for clients because .proto files will be
   253  in a single `proto/` directory which can be copied rather than scattered
   254  throughout the Cosmos SDK
   255  
   256  ### Negative
   257  
   258  ### Neutral
   259  
   260  * `.proto`  files will need to be reorganized and refactored
   261  * some modules may need to be marked as alpha or beta
   262  
   263  ## References