问题
I have an App-Engine service endpoint that is returning a POJO object consisting of many fields of various types. The Android client, built with the corresponding endpoint-libs, accepts this just fine.
If I add new fields to the end of this object definition and start returning that extended object from the App-Engine servers, will older Android clients accept this and just ignore the extra, or will they barf?
I see mention of support of different "versions" of an API, which seems to be required if I can't extend my return object, but information on how to write this is difficult to find. Any pointers?
Or, perhaps more simply... What is the best way to return different information to a REST call than previous server versions and still be backward compatible with older clients? Something like Objectify-for-Endpoints would be perfect.
回答1:
If the only changes you make are additive, previously generated clients should continue to work fine. I just tested a backend and Android client and they behaved correctly when I added a field to the POJO without updating the client.
There is a somewhat helpful table in the documentation that gives some guidance on when you should be incrementing API versions.
The relevant bits:
- When you want to introduce an incremental, but non-breaking change, keep the API version constant and deploy over the existing API.
- When you introduce a breaking change to your API, increment the API version.
Adding a field to your POJO should qualify as an incremental, non-breaking change. If you change the names or types of fields, you will likely need to increment the API version.
On hosting multiple API/App Engine versions
APIs are just classes with annotations, so if you want to add a new API version, just add a new class and specify a different version number in the annotation. You're free to make use of inheritance in designing your classes (see Multiclass APIs).
If you keep the App Engine version constant (or always refer to the default
version), the only thing that needs to change, client side, is the version of the API you are accessing. The client library builds in the version number, so if you generated a client library for v1
of your API, it will always access v1
of the API unless you modify the source. If you make additive changes to v1
of the API, the client library for v1
should continue to work (as noted above).
If you modify both the App Engine version and API version, things get a little trickier. You can have different v1
s of an API hosted on different (App Engine) versions of an app. By default, client libraries are going to point to the App Engine default
version, but you can override this in the client library by changing the root URL to point to a specific version (e.g. https://1-dot-myapp.appspot.com
).
My recommendation is to always have code that's shipped to customers point at your default
App Engine version (the major exception would be if you have some dogfood version of your app that can be easily updated). If you increment the App Engine version, make sure to include all API versions that you wish to support into that deployment.
回答2:
If you want to go all the way and create a completely flexible interface then consider returning a collection of Strings, where each string is a JSON'ed object. This means that you would do the JSON'ing yourself rather then letting endpoints do it, but that's easy.
[edit later]Just a correction for completeness. There is an issue with simply returning a collection of strings (see here). Instead, create a class that wraps the collection and return that.
来源:https://stackoverflow.com/questions/20111448/what-changes-can-i-make-to-a-cloud-endpoint-app-engine-return-object-before-i