-
Notifications
You must be signed in to change notification settings - Fork 532
Migration
This guide will highlight the major changes in the SDK and how to update your code accordingly. All changes in this guide are breaking changes unless otherwise specified.
The following services are now being generated programmatically:
- Discovery
- Conversation
- Natural Language Understanding
- Tone Analyzer
- Language Translator
- Personality Insights
- Visual Recognition.
It's important to note that with so many of the services being moved to automated generation, there are many minor changes to class organization, naming, etc. Therefore, this list is not exhaustive. However, we hope that this new approach will result in more consistent, maintainable code going forward.
Since most of this release was focused on the new approach of generating the SDKs, many of the changes are broad and encompassed in the first section below. Any service-specific changes will come afterward.
Before, some service methods had option parameters passed directly. An example of this can be found when creating a counterexample in the old Conversation service:
String workspaceId = "id";
String counterExampleText = "This is an old example of creating a counterexample";
ExampleResponse response = service.createCounterexample(workspaceId, counterExampleText).execute();
This was inconsistent, as other methods, even within the same service, sometimes used a separate "options" class to package the parameters. This change can be seen in the new release with the same method as above:
String workspaceId = "id";
String counterExampleText = "This is the new way to create a counterexample";
CreateCounterexampleOptions createOptions
= new CreateCounterexampleOptions.Builder(workspaceId, counterExampleText).build();
Counterexample response = service.createCounterexample(createOptions).execute();
This pattern should now be consistent across all of the listed services at the top of this guide, generally with "options' classes being split into "create", "update", "delete", etc.
This is not a breaking change.
Some objects returned by Watson services can have dynamic properties attached to them which are unspecified in the API reference and based on application-specific conditions. These can now be handled in classes which extend DynamicModel
. Here is an example of this in the Conversation service:
MessageResponse response = service.message(requestOptions).execute();
Context context = response.getContext();
// This property is specific to your application
String dynamicProperty = (String) context.get("dynamicStringProperty");
Classes extending DynamicModel
are backed by a HashMap<String, Object>
and can therefore be treated as such for the purposes of handling these dynamic properties.
Whether this is a breaking change or not will depend on the specific method.
Previously, methods which accepted files did so using the File
type. This is still supported in some methods, but the preferred standard in the generated services is to accept an InputStream
with the option of also specifying the content type and/or the name. As files can also be converted to an InputStream
, this adds flexibility to what kind of data can be passed to our services.
Here's an explicit example of the change found in the Visual Recognition service:
// Previous version with a File parameter
File image = new File("image.jpg");
ClassifyImagesOptions options = new ClassifyImagesOptions.Builder()
.imagesFile(image)
.build();
VisualClassification result = service.classify(options).execute();
// New version, converting the file to a FileInputStream
InputStream imageStream = new FileInputStream("image.jpg");
ClassifyOptions options = new ClassifyOptions.Builder()
.imagesFile(imagesStream)
.build();
ClassifiedImages result = service.classify(options).execute();
As mentioned earlier, it's now possible to explicitly specify the file content type. The easiest way to specify this is as a constant in the HttpMediaType
utility class. For example:
InputStream imageStream = new FileInputStream("images.zip");
ClassifyOptions options = new ClassifyOptions.Builder()
.imagesFile(imagesStream)
.imagesFileContentType(HttpMediaType.APPLICATION_ZIP)
.build();
ClassifiedImages result = service.classify(options).execute();
All methods related to deletion now return void
.
Before:
DeleteDocumentRequest deleteRequest =
new DeleteDocumentRequest.Builder(environmentId, collectionId, documentId).build();
DeleteDocumentResponse deleteResponse = discovery.deleteDocument(deleteRequest).execute();
Now:
DeleteDocumentOptions deleteOptions =
new DeleteDocumentOptions.Builder(environmentId, collectionId, documentId).build();
// No return value
discovery.deleteDocument(deleteOptions).execute();
The response code will give information as to whether a request failed or not.