Skip to content

Commit 068685c

Browse files
trmartin4harr1424
andauthored
chore(docs): Add API bindings section to root README
## 📔 Objective Adds documentation to the root README to describe how to consume and update API bindings. Includes changes from #622 in which @harr1424 identified issues with our local binding generation instructions as well. Despite this not being the preferred way to update bindings, it's important for those instructions to be accurate as well. Corresponding PR for removing the docs from Contributing Docs: bitwarden/contributing-docs#735. Related PR for adding more documentation to `bitwarden-core`: #618. ## 🚨 Breaking Changes <!-- Does this PR introduce any breaking changes? If so, please describe the impact and migration path for clients. If you're unsure, the automated TypeScript compatibility check will run when you open/update this PR and provide feedback. For breaking changes: 1. Describe what changed in the client interface 2. Explain why the change was necessary 3. Provide migration steps for client developers 4. Link to any paired client PRs if needed Otherwise, you can remove this section. --> ## ⏰ Reminders before review - Contributor guidelines followed - All formatters and local linters executed and passed - Written new unit and / or integration tests where applicable - Protected functional changes with optionality (feature flags) - Used internationalization (i18n) for all UI strings - CI builds passed - Communicated to DevOps any deployment requirements - Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team ## 🦮 Reviewer guidelines <!-- Suggested interactions but feel free to use (or not) as you desire! --> - 👍 (`:+1:`) or similar for great changes - 📝 (`:memo:`) or ℹ️ (`:information_source:`) for notes or general info - ❓ (`:question:`) for questions - 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion - 🎨 (`:art:`) for suggestions / improvements - ❌ (`:x:`) or ⚠️ (`:warning:`) for more significant problems or concerns needing attention - 🌱 (`:seedling:`) or ♻️ (`:recycle:`) for future improvements or indications of technical debt - ⛏ (`:pick:`) for minor or nitpick changes --------- Co-authored-by: John Harrington <[email protected]>
1 parent 948b207 commit 068685c

File tree

2 files changed

+136
-15
lines changed

2 files changed

+136
-15
lines changed

README.md

Lines changed: 135 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,39 +61,160 @@ are:
6161
- [`bitwarden-uniffi`](./crates/bitwarden-uniffi): Mobile bindings for swift and kotlin using
6262
[UniFFI](https://github.com/mozilla/uniffi-rs/).
6363

64-
## API Bindings
64+
## Server API Bindings
65+
66+
We auto-generate the server bindings using
67+
[openapi-generator](https://github.com/OpenAPITools/openapi-generator), which creates Rust bindings
68+
from the server OpenAPI specifications. These bindings are
69+
[regularly updated](https://github.com/bitwarden/sdk-internal/actions/workflows/update-api-bindings.yml)
70+
to ensure they stay in sync with the server.
71+
72+
The bindings are exposed as multiple crates, one for each backend service:
73+
74+
- [`bitwarden-api-api`](./crates//bitwarden-api-api/README.md): For the `Api` service that contains
75+
most of the server side functionality.
76+
- [`bitwarden-api-identity`](./crates/bitwarden-api-identity/README.md): For the `Identity` service
77+
that is used for authentication.
78+
79+
When performing any API calls the goal is to use the generated bindings as much as possible. This
80+
ensures any changes to the server are accurately reflected in the SDK. The generated bindings are
81+
stateless, and always expects to be provided a `Configuration` instance. The SDK exposes these under
82+
the `get_api_configurations` function on the `Client` struct.
83+
84+
You should not expose the request and response models of the auto-generated bindings and should
85+
instead define and use your own models. This ensures the server request / response models are
86+
decoupled from the SDK models and allows for easier changes in the future without breaking backwards
87+
compatibility.
88+
89+
We recommend using either the `From` or `TryFrom` conversion traits depending on if the conversion
90+
requires error handling or not. Below are two examples of how this can be done:
91+
92+
```rust
93+
# use bitwarden_crypto::EncString;
94+
# use serde::{Serialize, Deserialize};
95+
# use serde_repr::{Serialize_repr, Deserialize_repr};
96+
#
97+
# #[derive(Serialize, Deserialize, Debug, Clone)]
98+
# struct LoginUri {
99+
# pub uri: Option<EncString>,
100+
# pub r#match: Option<UriMatchType>,
101+
# pub uri_checksum: Option<EncString>,
102+
# }
103+
#
104+
# #[derive(Clone, Copy, Serialize_repr, Deserialize_repr, Debug, PartialEq)]
105+
# #[repr(u8)]
106+
# pub enum UriMatchType {
107+
# Domain = 0,
108+
# Host = 1,
109+
# StartsWith = 2,
110+
# Exact = 3,
111+
# RegularExpression = 4,
112+
# Never = 5,
113+
# }
114+
#
115+
# #[derive(Debug)]
116+
# struct VaultParseError;
117+
#
118+
impl TryFrom<bitwarden_api_api::models::CipherLoginUriModel> for LoginUri {
119+
type Error = VaultParseError;
120+
121+
fn try_from(uri: bitwarden_api_api::models::CipherLoginUriModel) -> Result<Self, Self::Error> {
122+
Ok(Self {
123+
uri: EncString::try_from_optional(uri.uri)
124+
.map_err(|_| VaultParseError)?,
125+
r#match: uri.r#match.map(|m| m.into()),
126+
uri_checksum: EncString::try_from_optional(uri.uri_checksum)
127+
.map_err(|_| VaultParseError)?,
128+
})
129+
}
130+
}
131+
132+
impl From<bitwarden_api_api::models::UriMatchType> for UriMatchType {
133+
fn from(value: bitwarden_api_api::models::UriMatchType) -> Self {
134+
match value {
135+
bitwarden_api_api::models::UriMatchType::Domain => Self::Domain,
136+
bitwarden_api_api::models::UriMatchType::Host => Self::Host,
137+
bitwarden_api_api::models::UriMatchType::StartsWith => Self::StartsWith,
138+
bitwarden_api_api::models::UriMatchType::Exact => Self::Exact,
139+
bitwarden_api_api::models::UriMatchType::RegularExpression => Self::RegularExpression,
140+
bitwarden_api_api::models::UriMatchType::Never => Self::Never,
141+
}
142+
}
143+
}
144+
```
145+
146+
### Updating bindings after a server API change
147+
148+
When the API exposed by the server changes, new bindings will need to be generated to reflect this
149+
change for consumption in the SDK. Examples of such changes include adding new fields to server
150+
request / response models, removing fields from models, or changing types of models.
151+
152+
A GitHub workflow exists to
153+
[update the API bindings](https://github.com/bitwarden/sdk-internal/actions/workflows/update-api-bindings.yml).
154+
This workflow should always be used to merge any binding changes to `main`, to ensure that there are
155+
not conflicts with the auto-generated bindings in the future. Binding changes should **not** be
156+
included as a part of the PR to consume them.
157+
158+
There are two ways to run the workflow:
159+
160+
1. Manually run the `Update API Bindings`
161+
[workflow](https://github.com/bitwarden/sdk-internal/actions/workflows/update-api-bindings.yml)
162+
in the `sdk-internal` repo.
163+
2. Wait for an automatic binding update to run, which is scheduled every 2 weeks.
65164

66-
We autogenerate the server bindings using
67-
[openapi-generator](https://github.com/OpenAPITools/openapi-generator). To do this, we first need to
68-
build the internal swagger documentation.
165+
Both of these will generate a PR that will require approval from any teams whose owned code is
166+
affected by the binding updates.
69167

70-
### Swagger generation
168+
A suggested workflow for incorporating server API changes into the SDK would be:
71169

72-
The first step is to generate the swagger documents from the root of the server repository.
170+
1. Make changes in `server` repo to expose the new API.
171+
2. Merge `server` changes to `main`.
172+
3. Trigger the `Update API Bindings` workflow in `sdk-internal` to open a pull request with the
173+
updated API bindings.
174+
4. Review and merge that pull request to `sdk-internal` `main` branch.
175+
5. Pull in `sdk-internal` `main` into your feature branch for SDK work.
176+
6. Consume new API models in SDK code.
177+
178+
#### Local binding updates
179+
180+
> [!IMPORTANT] Use the [workflow](#updating-bindings-after-a-server-api-change) to make any merged
181+
> binding changes. Running the scripts below can be helpful during local development, but please
182+
> ensure that any changes to the bindings in `bitwarden-api-api` and `bitwarden-api-identity` are
183+
> **not** checked into any pull request.
184+
185+
In order to update the bindings locally, we first need to build the internal Swagger documentation.
186+
This code should not be directly modified. Instead use the instructions below to generate Swagger
187+
documents and use these to generate the OpenApi bindings.
188+
189+
#### Swagger generation
190+
191+
The first step is to generate the Swagger documents from the root of the
192+
[server repository](https://github.com/bitwarden/server).
73193

74194
```bash
75195
pwsh ./dev/generate_openapi_files.ps1
76196
```
77197

78-
### OpenApi Generator
198+
#### OpenApi Generator
79199

80200
To generate a new version of the bindings, run the following script from the root of the SDK
81-
project.
201+
project. This requires a Java Runtime Environment, and also assumes the repositories `server` and
202+
`sdk-internal` have the same parent directory.
82203

83204
```bash
84205
./support/build-api.sh
85206
```
86207

87208
This project uses customized templates that live in the `support/openapi-templates` directory. These
88-
templates resolve some outstanding issues we've experienced with the rust generator. But we strive
209+
templates resolve some outstanding issues we've experienced with the Rust generator. But we strive
89210
towards modifying the templates as little as possible to ease future upgrades.
90211

91-
### Note
212+
:::note
213+
214+
If you don't have the nightly toolchain installed, the `build-api.sh` script will install it for
215+
you.
92216

93-
- If you don't have the nightly toolchain installed, the `build-api.sh` script will install it for
94-
you.
95-
- This process also changes the `Cargo.toml` file. When creating a PR updating the bindings, please
96-
revert (do not include) the updates to the `Cargo.toml` file.
217+
:::
97218

98219
## Developer tools
99220

crates/bitwarden-core/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Bitwarden Core
22

33
Contains core functionality used by the feature crates. For an introduction to the Bitwarden SDK and
4-
the `bitwarden-core` create please refer to the
4+
the `bitwarden-core` crate please refer to the
55
[SDK Architecture](https://contributing.bitwarden.com/architecture/sdk/) documentation.
66

77
<div class="warning">

0 commit comments

Comments
 (0)