Search code examples
javaelasticsearchopensearch

Is there a way to do Raw JSON Requests using the Opensearch Java Client?


The Opensearch Java Client does not have methods which take it in raw JSON requests.

All of the methods require some Java POJO/Class to exist before doing a request such creating an index or even adding a document to an index.

I have tried to use the JSON Deserializers and also using the Jackson ObjectMapper to convert the JSON to the Opensearch Request types but it doesn't have a native mapping for it.


Solution

  • I don't think there is a supported way to do this. The JSON Deserializers seem to only be meant for the JSON body of the respective request (i.e. the "aliases", "mappings" and "settings" in your CreateIndexRequest) so any non-nullable field that is not part of the expected JSON body would need to be passed in separately. The currently exposed methods don't really allow for this. One hacky way is to setup your own deserializer using the protected (!) setup methods of the API using Reflection.

    Example:

    private static ObjectDeserializer<CreateIndexRequest.Builder> getDeserializerWithPreconfiguredBuilder(
                Supplier<CreateIndexRequest.Builder> builderSupplier) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
      Class<CreateIndexRequest> clazz = CreateIndexRequest.class;
      Method method = clazz.getDeclaredMethod("setupCreateIndexRequestDeserializer", ObjectDeserializer.class);
      method.setAccessible(true);
    
      ObjectDeserializer<CreateIndexRequest.Builder> deserializer = new ObjectDeserializer<>(builderSupplier);
      method.invoke(null, deserializer);
      return deserializer;
    }
    

    and then

    JsonParser jsonParser = JsonProvider.provider().createParser(new StringReader("{}")); // <-- your JSON request body
    Supplier<CreateIndexRequest.Builder> builderSupplier = () -> new CreateIndexRequest.Builder().index("my-index");
    ObjectDeserializer<CreateIndexRequest.Builder> deserializer = getDeserializerWithPreconfiguredBuilder(builderSupplier);
    CreateIndexRequest req = deserializer.deserialize(jsonParser, new JsonbJsonpMapper()).build();
    

    Btw: Elasticsearch has added raw JSON support to the API. OpenSearch could draw some inspiration there.