-
Notifications
You must be signed in to change notification settings - Fork 40
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
[Runtime] Add support of deepObject style in query params #100
Conversation
### Motivation apple#259 ~Depends on apple/swift-openapi-runtime#100 landing first and getting released, and the version dependency being bumped here.~ ### Modifications Added `deepObject` style to serializer & parser in order to support nested keys on query parameters. ### Result Support nested keys on query parameters. ### Test Plan Adapted snippet tests (SnippetBasedReferenceTests)
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.
First off, thanks @kstefanou52 for taking a stab at this. I've taken a brief look over the code and left some comments. I imagine @czechboy0 will have some to add too.
Tests/OpenAPIRuntimeTests/URICoder/Test_URICodingRoundtrip.swift
Outdated
Show resolved
Hide resolved
f421950
to
28265a7
Compare
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.
Thanks for kicking off this work, @kstefanou52! A few comments, but overall this is the right approach.
Sources/OpenAPIRuntime/URICoder/Serialization/URISerializer.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Encoding/Test_URIEncoder.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Serialization/Test_URISerializer.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Serialization/Test_URISerializer.swift
Show resolved
Hide resolved
Hello, looks like all the test cases except for the In this implementation it looks like the formDataExplode behavior is being used as a fallback for the undefined behavior from deepObjectExplode, is that intentional? |
@alephao yes these were called out in the review, see the code comments and expand the resolved ones (they don't seem to actually be updated in code yet). |
@czechboy0 Oh, sorry, I got a bit lost in the comments and missed that one! @kstefanou52 since this been stuck for a few weeks, I sent a PR to your fork addressing most of the requested changes (not sure if it's all there cuz I got a bit lost in the comments) kstefanou52#1 This is a summary of the changes:
|
@czechboy0 @alephao Sorry I was away from keyboard the last 2 weeks due to vacations. I have fixed the majority of the comments and I'll push it at the of the day. |
28265a7
to
c2ab707
Compare
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.
Thanks for the updates, a few more comments
Sources/OpenAPIRuntime/URICoder/Serialization/URISerializer.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Serialization/Test_URISerializer.swift
Outdated
Show resolved
Hide resolved
Hi @kstefanou52, I'm sorry that I'm being annoying but I really want this change in the upstream and the PR seem to be stuck, I updated my PR to your fork with your new changes, it already addresses all the requested changes by @czechboy0, please have a look there or if you don't have time to keep working on this I'm happy to open another PR and I can put my focus on it and finish the work you've been doing. Again, sorry to push, I just want this feature merged soon! |
@alephao I'll push my changes until the end of day. |
c2ab707
to
76951d7
Compare
### Motivation The runtime changes for: apple/swift-openapi-generator#259 ### Modifications Added `deepObject` style to serializer & parser in order to support nested keys on query parameters. ### Result Support nested keys on query parameters. ### Test Plan These are just the runtime changes, tested together with generated changes.
Hello @simonjbeaumont @czechboy0 ! I just pushed my changes. the only thing that I'm still missing are the comments you left about Test_URiParser with the square brackets. I think that the tests are correct because it tests the nested parsing. Am I missing something ? thank you so much for the guidance and sorry for the delay. cheers! |
@kstefanou52 thanks for the updates! I'm going to try to explain @czechboy0's points since I do agree with the changes he has requested. Following the matrix here, the spec doesn't define the behavior of "empty", "string" or "array" unless the document is using a spec extension. My interpretation of it is that primitives like Imagine the following concrete example: I have an endpoint to update user's first and last name, I like to model my sever using the deepObject style, so the decoders on my server work on inputs like Now imagine a mocked server generated by this library, if it accepts Now what that means in terms of code that needs to be changed here is that all the URIParser's tests should stop handling the "primitive=value" case, there should be an assertion that an empty dictionary was generated (meaning that the incorrect input was ignored) or it should assert that an error was thrown. When looking at the empty test case of the Please let me know if this makes any sense or if I'm completely wrong |
@alephao if I'm not wrong @czechboy0 requested to oarse using square braces and not ignore them. But to be honest I'm not completely sure. Let's wait for his response. |
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.
@kstefanou52 about the brackets check the suggestions below, there is also a request to create test cases for non-escaped brackets
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Yeah @alephao is exactly right here - unsupported types of objects need to throw an error, but should not parse as if they were simple/form. |
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.
The code looks okay now, just the tests need updating based on @alephao and my comments. 🙏
Tests/OpenAPIRuntimeTests/URICoder/Parsing/Test_URIParser.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Serialization/Test_URISerializer.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIRuntimeTests/URICoder/Serialization/Test_URISerializer.swift
Outdated
Show resolved
Hide resolved
Hello @czechboy0 and @alephao, could you please take a look at |
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.
Hi @kstefanou52, let me know if I'm wrong, but I believe that the point of these roundtrip tests is to check that a successfully encoded value can also be decoded, all the tests expecting errors won't encode nor decode anything, so they end up missing the point.
I think would be nice if we could do something like this:
// Note: This code won't work, it's just an idea
deepObjectExplode: .custom(
"obj[who]=fred",
value: ["who": "fred"]
)
But that code won't work, I pulled your latest changes and spent a bit of time hammering a way to test the deepObject in the current setup (with the _test
function), but I wasn't happy with anything I tried, code was getting spaghetti and hard to reason about.
So I tried writing a separate function to test deepObjects which ended up working well. It's almost the same as the generic code in _test
.
// func definition
func _testDeepObject<T: Codable & Equatable>(key: String, value: T, encodedString string: String, file: StaticString = #file, line: UInt = #line) throws {
let encoder = URIEncoder(configuration: .deepObjectExplode)
let encodedString = try encoder.encode(value, forKey: key)
XCTAssertEqual(encodedString, string, "Variant: deepObjectExplode", file: file, line: line)
let decoder = URIDecoder(configuration: .deepObjectExplode)
let decodedValue = try decoder.decode(T.self, forKey: key, from: encodedString[...])
XCTAssertEqual(decodedValue, value, "Variant: deepObjectExplode", file: file, line: line)
}
// usage example
try _testDeepObject(key: "obj", value: ["root": "Hello World!"], encodedString: "obj%5Broot%5D=Hello%20World%21")
I'm not sure if it's the best approach, but it does work and it fulfills what I believe to be the goal of these tests
Thank you @alephao for reviewing it. I completely agree with your comment. However, since we are only supporting encoding dictionaries and not primitive values, I thought it would be appropriate to throw the necessary error and test this behavior. Let's wait for @czechboy0 to confirm how we should proceed. |
Yes let's only support dictionaries, by my read of the specification, that's the only type that has defined rules. It's better to throw an error for anything else, and if we figure out that there are other types we should support, we can always add them. But adding them is easier than removing them :) |
@czechboy0, are there any further changes needed? I apologize for being a bit lost with all these conversations. Thank you! |
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.
Ok looks good to me! Let's run the CI and get that to green now.
@swift-server-bot test this please |
The API breakage failure is expected:
It's in the SPI that only generated code uses, so it's okay to allow this "breakage" (it's not really, it was designed to be extended). |
Ok soundness failed, please run this locally and check in the changes:
|
@swift-server-bot test this please |
d1dc2bb
to
9633ee2
Compare
@czechboy0, I think the soundness check must be green now. |
@swift-server-bot test this please |
apple#259 ~Depends on apple/swift-openapi-runtime#100 landing first and getting released, and the version dependency being bumped here.~ Added `deepObject` style to serializer & parser in order to support nested keys on query parameters. Support nested keys on query parameters. Adapted snippet tests (SnippetBasedReferenceTests)
Motivation
The runtime changes for:
apple/swift-openapi-generator#259
Modifications
Added
deepObject
style to serializer & parser in order to support nested keys on query parameters.Result
Support nested keys on query parameters.
Test Plan
These are just the runtime changes, tested together with generated changes.