-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Utoipa for the solvers crate #2668
base: main
Are you sure you want to change the base?
Conversation
# Conflicts: # crates/solvers-dto/src/auction.rs
f3896c8
to
e469368
Compare
crates/solvers/openapi.yml
Outdated
- preInteractions | ||
- postInteractions | ||
- sellTokenSource | ||
- buyTokenDestination |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is new because we forgot to alter it in the #2620
@@ -0,0 +1,37 @@ | |||
use utoipa::ToSchema; | |||
|
|||
// Structs for the utoipa OpenAPI schema generator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These structs should be used directly in the code. Worth a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks very promising!
#[serde(rename_all = "lowercase")] | ||
pub enum SigningScheme { | ||
pub enum LegacySigningScheme { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like these two enums are exactly the same. Can we not combine them? Why is one considered more legacy than the other?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because from the aution side we have lowercased variants while from the solution - camelCase.
services/crates/solvers-dto/src/auction.rs
Lines 139 to 141 in e469368
// todo: There is a conflict between solution's SigningScheme which is in | |
// camelCase. There is no way to keep 2 object with the same name in the OpenAPI | |
// schema. Temporarily renamed the struct. Must be migrated to the camelCase. |
// todo: Currently, it strictly follows the manual api schema. This has to be | ||
// automated and deleted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something blocking this PR or just future work to make working with this code more ergonomic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR aims to automate the OpenAPI schema generation without altering its structure. In separate PRs, it would be good to try to remove manual ToSchema
implementations, but this will change the schema structures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work. I hope we can use this initiative to introduce commonly shared structs across the different crates. I.e. we probably don't have to have a TokenAmount
struct in every binary.
crates/solvers/src/api/mod.rs
Outdated
@@ -46,3 +47,74 @@ impl Api { | |||
server.with_graceful_shutdown(shutdown).await | |||
} | |||
} | |||
|
|||
// migrate to utoipauto once the issue is solved https://github.com/ProbablyClem/utoipauto/issues/23 | |||
pub fn generate_openapi_yaml() -> Result<String, serde_yaml::Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems a bit backwards to generate this from the solvers
repo. From my view the driver is the one dictating the interface so it makes more sense to me to derive the openapi spec from it's requests and expected responses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gnosis/solvers
will generate the yaml file from the same crate. IMO, that should live where the API server with all the endpoints is declared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plugged in the generated yaml file into a openapi viewer and a bunch of things get displayed weird:
- token addresses (and other hex strings) get interpreted as floats
- liquidity entries have a bunch of weird properties in the examples:
"tokens": {
"additionalProp1": {
"balance": "1234567890",
"scalingFactor": "13.37",
"weight": "13.37"
},
...
Probably makes sense to tweak the PR and sanity check with https://editor.swagger.io/ until things look good.
Found the issue with HEX values: juhaku/utoipa#875. The fastest way would be provide examples with strings length up to 35.
The original yaml contains the same issue. I can try to fix it in a separate PR. |
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
#[serde_as(as = "Option<DisplayFromStr>")] | ||
#[schema(value_type = String)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this correct to be type String
? shouldn't it be integer?
pub id: Option<i64>, | ||
pub tokens: HashMap<H160, Token>, | ||
/// A map of token addresses to token information. | ||
pub tokens: HashMap<H160, TokenInfo>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't there a way to add the value type also the token? the H160
is type address 🤔
pub buy_token: H160, | ||
#[schema(value_type = TokenAmount)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think of creating a "Deserializable" type called TokenAmount
(if it doesn't exist already), derive the proper schema to the new type, and use the type all over the deserializable structs?
@@ -200,6 +426,52 @@ pub struct WeightedProductPool { | |||
pub version: WeightedProductVersion, | |||
} | |||
|
|||
impl ToSchema<'static> for WeightedProductPool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this can be directly derived in the #[derive()]
?
@@ -178,9 +373,40 @@ pub struct ConstantProductPool { | |||
pub fee: BigDecimal, | |||
} | |||
|
|||
impl ToSchema<'static> for ConstantProductPool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this can be directly derived in the #[derive()]
?
#[schema( | ||
example = "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" | ||
)] | ||
#[allow(dead_code)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why all of this dead code?
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
Description
Initial step to the automated OpenAPI schema generation. The implementation strictly follows the current manually created OpenAPI schema to avoid breaking changes. That is the main reason why some of the structs have manually implemented
ToSchema
trait.Changes
crates/solvers/openapi.yml
is now generated usingcargo build
openapi-generator
which implements a workaround found by communitypull-request
CI job is modified and now fails if the schema changes weren't included in the commitHow to review
crates/solver/openapi.yml
file can be compared with the previous state: https://github.com/cowprotocol/services/blob/03748ae9d04456f34c71751926c861357dc1018d/crates/solvers/openapi.ymlHow to test
Existing tests + staging.
Related Issues
Partly fixes #2203
Further steps
gnosis/solvers
repoutoipauto
, but currently, it is not really stable(#[derive(utoipa::ToSchema)]
detection fails ProbablyClem/utoipauto#23)