ComponentHasDynamicDataSchema

Add this interface to your component to add support for a dynamic input or output schema. This is typically useful when the schema is determined by the configuration of your app or component - e.g. selecting a particular table in a database or providing a particular query.

Applies to: All data-* component types

Source: Github

Example (data-source):

package my.org.components;

import io.dexi.service.AppContext;
import io.dexi.service.DynamicSchemaConfig;
import io.dexi.service.Schema;
import io.dexi.service.components.AppComponent;
import io.dexi.service.components.ComponentHasDynamicDataSchema;
import io.dexi.service.components.DataSourceAppComponent;
import io.dexi.service.utils.ResultStream;
import my.org.data.MyAppConfig;
import my.org.data.MyComponentConfig;

@AppComponent("read-data-from-my-app")
public class MyAppDataSourceAppComponent implements DataSourceAppComponent<MyAppConfig, MyComponentConfig>,
                                                    ComponentHasDynamicDataSchema<MyAppConfig, MyComponentConfig> {


    @Override
    public void read(AppContext<MyAppConfig, MyComponentConfig> ctxt, String offset, int batchSize, ResultStream resultStream)  {
        /* ... component implementation ... */
    }

    @Override
    public Schema getSchema(AppContext<MyAppConfig, DynamicSchemaConfig<MyComponentConfig>> ctxt) {
        Schema schema = new Schema();
        final Schema.Field dynamicField = new Schema.Field();
        dynamicField.setTitle("A dynamic field");
        dynamicField.setRequired(true);
        schema.put("myFirstField", dynamicField);
        return schema;
    }

    @Override
    public Class<MyComponentConfig> getComponentConfigClass() {
        return MyComponentConfig.class;
    }
}
components:
- name: read-data-from-my-app
  type: data-source
  title: Read data from my app
  specification:
    endpoint:
      url: "${baseUrl}/dexi/data/source/read"
      method: POST
    dynamicOutputs: # Add the dynamic schema endpoint here
      url: "${baseUrl}/dexi/data/dynamic-schema/read"
      method: POST

Example (data-storage):

package my.org.components;

import io.dexi.service.AppContext;
import io.dexi.service.DynamicSchemaConfig;
import io.dexi.service.Schema;
import io.dexi.service.components.AppComponent;
import io.dexi.service.components.ComponentHasDynamicDataSchema;
import io.dexi.service.components.DataStorageAppComponent;
import io.dexi.service.utils.RowStream;
import my.org.data.MyAppConfig;
import my.org.data.MyComponentConfig;
import my.org.data.SomeRepository;

import java.io.IOException;
import java.util.Map;

@AppComponent("write-data-to-my-app")
public class MyAppDataStorageAppComponent implements DataStorageAppComponent<MyAppConfig, MyComponentConfig>,
        ComponentHasDynamicDataSchema<MyAppConfig, MyComponentConfig> {

    private final SomeRepository someRepository;

    public MyAppDataStorageAppComponent(SomeRepository someRepository) {
        this.someRepository = someRepository;
    }

    @Override
    public Object write(AppContext<MyAppConfig, MyComponentConfig> ctxt,                 /* ... component implementation ... */
    }

    @Override
    public Schema getSchema(AppContext<MyAppConfig, DynamicSchemaConfig<MyComponentConfig>> ctxt) {
        Schema schema = new Schema();
        final Schema.Field dynamicField = new Schema.Field();
        dynamicField.setTitle("A dynamic field");
        dynamicField.setRequired(true);
        schema.put("myFirstField", dynamicField);
        return schema;
    }

    @Override
    public Class<MyComponentConfig> getComponentConfigClass() {
        return MyComponentConfig.class;
    }
}
components:
- name: read-data-from-my-app
  type: data-source
  title: Read data from my app
  specification:
    endpoint:
      url: "${baseUrl}/dexi/data/storage/write"
      method: POST
    dynamicInputs: # Add the dynamic schema endpoint here
        url: "${baseUrl}/dexi/data/dynamic-schema/read"
      method: POST