Implementation:Apache Paimon RESTApi
| Knowledge Sources | |
|---|---|
| Domains | REST Catalog, HTTP Client, Catalog Operations |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
RESTApi is the main public API class for interacting with a Paimon REST catalog server, providing methods for all catalog operations via REST HTTP calls.
Description
RESTApi (public API since 1.2.0) initializes with Options containing server URI, warehouse, and authentication configuration. On construction, it optionally fetches and merges server-side configuration via a /v1/config endpoint. The class uses HttpClient for HTTP transport and RESTAuthFunction for authentication, building resource paths via ResourcePaths.
The API provides comprehensive catalog lifecycle operations: list/create/get/alter/drop for databases, tables, views, and functions; partition management; branch and tag operations; snapshot queries; and table token/auth operations. It supports paginated APIs by iterating through pages using listDataFromPageApi. The class also provides static JSON serialization/deserialization utilities via toJson/fromJson using Jackson ObjectMapper.
This is the central entry point for lightweight REST catalog access in Paimon. It is designed to be dependency-light with no Hadoop or file system dependencies, enabling client applications to interact with Paimon catalogs purely through REST. This is the primary API that end users and integrations use to manage Paimon metadata remotely.
Usage
Use RESTApi to interact with a Paimon REST catalog server for creating, reading, updating, and deleting databases, tables, views, functions, and related metadata.
Code Reference
Source Location
- Repository: Apache_Paimon
- File: paimon-api/src/main/java/org/apache/paimon/rest/RESTApi.java
- Lines: 1-1469
Signature
@Public
public class RESTApi {
public static final String HEADER_PREFIX = "header.";
public static final String MAX_RESULTS = "maxResults";
public static final String PAGE_TOKEN = "pageToken";
private final HttpClient client;
private final RESTAuthFunction restAuthFunction;
private final Options options;
private final ResourcePaths resourcePaths;
// Constructors
public RESTApi(Options options);
public RESTApi(Options options, boolean configRequired);
// Configuration
public Options options();
// Database operations
public List<String> listDatabases();
public PagedList<String> listDatabasesPaged(Integer maxResults, String pageToken, String pattern);
public void createDatabase(String name, Map<String, String> properties);
public GetDatabaseResponse getDatabase(String name);
public void dropDatabase(String name);
public void alterDatabase(String name, List<String> removals, Map<String, String> updates);
// Table operations
public List<String> listTables(String databaseName);
public PagedList<String> listTablesPaged(String databaseName, Integer maxResults,
String pageToken, String pattern, String type);
public GetTableResponse getTable(Identifier identifier);
public void createTable(Identifier identifier, Schema schema);
public void renameTable(Identifier fromTable, Identifier toTable);
public void alterTable(Identifier identifier, List<SchemaChange> changes);
public void dropTable(Identifier identifier);
// Snapshot operations
public TableSnapshot loadSnapshot(Identifier identifier);
public Snapshot loadSnapshot(Identifier identifier, String version);
public PagedList<Snapshot> listSnapshotsPaged(Identifier identifier,
Integer maxResults, String pageToken);
public boolean commitSnapshot(Identifier identifier, String tableUuid,
Snapshot snapshot, List<PartitionStatistics> statistics);
public void rollbackTo(Identifier identifier, Instant instant);
// View operations
public GetViewResponse getView(Identifier identifier);
public void createView(Identifier identifier, ViewSchema schema);
public void dropView(Identifier identifier);
public void alterView(Identifier identifier, List<ViewChange> viewChanges);
// Function operations
public List<String> listFunctions(String databaseName);
public GetFunctionResponse getFunction(Identifier identifier);
public void createFunction(Identifier identifier, Function function);
public void dropFunction(Identifier identifier);
public void alterFunction(Identifier identifier, List<FunctionChange> changes);
// Utility methods
public static <T> T fromJson(String json, Class<T> clazz);
public static <T> String toJson(T t);
}
Import
import org.apache.paimon.rest.RESTApi;
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| options | Options | yes | Configuration including URI, warehouse, authentication |
| identifier | Identifier | yes (for operations) | Database and object name |
| schema | Schema | no | Table or view schema for creation |
| changes | List<SchemaChange/ViewChange/FunctionChange> | no | Mutation operations |
Outputs
| Name | Type | Description |
|---|---|---|
| databases | List<String> | Database names |
| tables | List<String> | Table names |
| tableResponse | GetTableResponse | Table metadata |
| snapshot | Snapshot/TableSnapshot | Snapshot metadata |
| success | boolean | Operation success status |
Usage Examples
Initializing REST API Client
import org.apache.paimon.rest.RESTApi;
import org.apache.paimon.options.Options;
import org.apache.paimon.rest.RESTCatalogOptions;
import static org.apache.paimon.options.CatalogOptions.WAREHOUSE;
// Configure REST client
Options options = new Options();
options.set(RESTCatalogOptions.URI, "http://localhost:8080");
options.set(WAREHOUSE, "my_warehouse");
options.set("header.Authorization", "Bearer token123");
// Initialize API (with config fetch)
RESTApi api = new RESTApi(options);
// Or skip config fetch if options already merged
RESTApi api2 = new RESTApi(options, false);
// Get merged options
Options mergedOptions = api.options();
Database Operations
import org.apache.paimon.rest.RESTApi;
import org.apache.paimon.PagedList;
import java.util.HashMap;
import java.util.Map;
RESTApi api = new RESTApi(options);
// List all databases
List<String> databases = api.listDatabases();
System.out.println("Databases: " + databases);
// List databases with pagination
PagedList<String> pagedDatabases = api.listDatabasesPaged(10, null, "test%");
System.out.println("First page: " + pagedDatabases.getElements());
System.out.println("Next token: " + pagedDatabases.getNextPageToken());
// Create database
Map<String, String> props = new HashMap<>();
props.put("owner", "user1");
api.createDatabase("my_database", props);
// Get database info
GetDatabaseResponse dbResponse = api.getDatabase("my_database");
System.out.println("Database: " + dbResponse.name());
// Alter database
api.alterDatabase("my_database",
Arrays.asList("old-prop"),
Map.of("new-prop", "new-value"));
// Drop database
api.dropDatabase("my_database");
Table Operations
import org.apache.paimon.rest.RESTApi;
import org.apache.paimon.catalog.Identifier;
import org.apache.paimon.schema.Schema;
import org.apache.paimon.types.DataTypes;
RESTApi api = new RESTApi(options);
// Create table
Schema schema = Schema.newBuilder()
.column("id", DataTypes.INT())
.column("name", DataTypes.STRING())
.column("age", DataTypes.INT())
.primaryKey("id")
.option("bucket", "4")
.build();
Identifier tableId = Identifier.create("my_db", "my_table");
api.createTable(tableId, schema);
// List tables
List<String> tables = api.listTables("my_db");
System.out.println("Tables: " + tables);
// Get table
GetTableResponse tableResponse = api.getTable(tableId);
System.out.println("Table UUID: " + tableResponse.uuid());
System.out.println("Location: " + tableResponse.location());
// Alter table
List<SchemaChange> changes = Arrays.asList(
SchemaChange.addColumn("email", DataTypes.STRING()),
SchemaChange.setOption("compaction.max.file.num", "50")
);
api.alterTable(tableId, changes);
// Drop table
api.dropTable(tableId);
Snapshot Operations
import org.apache.paimon.rest.RESTApi;
import org.apache.paimon.catalog.Identifier;
import org.apache.paimon.Snapshot;
import org.apache.paimon.table.TableSnapshot;
import org.apache.paimon.PagedList;
RESTApi api = new RESTApi(options);
Identifier tableId = Identifier.create("my_db", "my_table");
// Load latest snapshot
TableSnapshot latestSnapshot = api.loadSnapshot(tableId);
System.out.println("Latest snapshot ID: " + latestSnapshot.id());
System.out.println("Record count: " + latestSnapshot.recordCount());
// Load specific snapshot version
Snapshot snapshot = api.loadSnapshot(tableId, "5");
System.out.println("Snapshot 5 timestamp: " + snapshot.timeMillis());
// List snapshots with pagination
PagedList<Snapshot> snapshots = api.listSnapshotsPaged(tableId, 10, null);
for (Snapshot s : snapshots.getElements()) {
System.out.println("Snapshot " + s.id() + ": " + s.commitKind());
}
// Rollback to snapshot
api.rollbackTo(tableId, Instant.fromSnapshot(3L));
Function Operations
import org.apache.paimon.rest.RESTApi;
import org.apache.paimon.catalog.Identifier;
import org.apache.paimon.function.Function;
import org.apache.paimon.function.FunctionChange;
import org.apache.paimon.function.FunctionDefinition;
RESTApi api = new RESTApi(options);
// Create function
FunctionDefinition definition = new FunctionDefinition(
"com.example.MyUDF",
"java",
null
);
Function function = new Function(
"my_function",
"java",
definition,
"My custom UDF",
Map.of()
);
Identifier funcId = Identifier.create("my_db", "my_function");
api.createFunction(funcId, function);
// List functions
List<String> functions = api.listFunctions("my_db");
System.out.println("Functions: " + functions);
// Get function
GetFunctionResponse funcResponse = api.getFunction(funcId);
System.out.println("Function: " + funcResponse.name());
// Alter function
List<FunctionChange> changes = Arrays.asList(
FunctionChange.setOption("timeout", "30s"),
FunctionChange.updateComment("Updated function")
);
api.alterFunction(funcId, changes);
// Drop function
api.dropFunction(funcId);