How to handle deprecation and breaking changes #1020
Replies: 1 comment
-
Handling breaking changes with REST APIs is definitely difficult, and I think designing a proper solution will take some discussion.
This doesn't sound quite right—at least for the intended behavior of the generator. If validation outright fails because a required property is missing, the API function should return
We could add some sort of dynamic look-up functionality to fall back to, but that will have a few issues:
Other possible solutionsIn general, making breaking changes to REST APIs is difficult—it's one of the main reasons GraphQL is used. Typically, you add a new endpoint with a Make everything optionalThis is the approach of openapi-generator (last I checked). Always assume that any field could be missing, even if the document says it's In my opinion, APIs who want to take this approach should do it in the document, rather than code generators making that choice for you and your users. So to implement that for this generator, go delete every Make deprecated fields optionalWe could automatically make Again, API maintainers can do this today without a change to this project—just also remove the Only deserialize the fields being usedThis is sort of like what you suggested above, but rather than moving everything to access-time validation, have consumers write a sub-model of the model they're interested in using. I'm not sure if it's even possible to represent this type-safely with Python's type system. In any event, this sounds like just a worse GraphQL, so I don't think it's worth pursuing 😬. All of this is to say, I don't see a clear path forward to a feature for this project that would make the deprecation dance any easier—but I think it's a super interesting topic that should be discussed more. I'm definitely open to ideas, but they'd need to improve deprecation without hurting the standard developer experience (type annotations can't get less accurate, errors can't get harder to understand). So... what do folks think? Is there any prior art from other client generators that we can take inspiration from? I should also say, in general this project takes the stance that the document should be accurate, and the client shouldn't do too much to compensate for that. This is why, for example, there is a distinction between a property being nullable and a property being not required—even though many APIs document the behavior incorrectly. |
Beta Was this translation helpful? Give feedback.
-
I was using a generated Python client for an API that had a deprecated
password
field. This generated client was being used in our production environment. Then the API removed the deprecatedpassword
field. We expected that this would have no effect on us because we weren't using it.Unfortunately it made it so that our Python client for the API could no longer deserialize the response into the model for it, so when we accessed the
host
field of the response (i.e.response.host
) anAttributeError
was raised. This is because when the generated Python client fails to deserialize a response into a model, it returns a dictionary instead. The dictionary had thehost
field we were trying to access, but it would need to be accessed via__getitem__
, i.e.response['host']
instead ofresponse.host
. This caused an outage in production until we updated our Python client to expect the new response that lacked thepassword
field.We're now trying to find a way to avoid this sort of outage in the future. One way I can think to avoid this problem would be to have the generated client do something like so:
Using
response.host
as an example, this would first try to access the field normally,response.host
, and then fall back toresponse['host']
ifresponse.host
raised anAttributeError
. If the fallback doesn't work, the original exception is raised.Along with an approach like this, logging a warning that the response could not be deserialized would be valuable.
If something like this were implemented, then instead of our system experiencing an outage when the API we rely on removed a field, we would have stated to see warnings that the API client is failing to deserialize the responses. Then we could've updated the client to reflect the removed field, and experienced no downtime.
Beta Was this translation helpful? Give feedback.
All reactions