Skip to main content
Version: v3

RESTful API V1

Verify

To use RESTful API, you must first obtain Personal Access Token, and attach it to Request headers.

headers: {
Authorization: `Token <Your Personal Access Token>`
}

Cache-Control

When using POST /query to execute Query, you can use the following two parameters to control the Cache of Query in the body

  1. cacheTTL: This value is the number of seconds, representing how long the Query Cache should be stored. For example, if it is set to 3600 (seconds), it means that if the Query result in the Cache exceeds 3600 seconds, the Query will be re-executed and fetch new information.
  2. cacheRefresh: Boolean value, "true" or "false", represents whether to ignore the Cache and re-execute the Query

To use the Cache mechanism, you must set both parameters.

API Endpoint

The API endpoint is the part of the web page URL to /web, plus /api/v1, for example: https://web.default.myname.apps.cannerdata.com/web/api/v1

Params & Input

In this document, the information carried by the request is divided into three types

  • Params: eg, id in /resource/:id.
  • Query String: For example, workspaceId in /resource?workspaceId=<workspaceId>.
  • Input: The data in Request Body, unified into JSON Object.

Workspace ID

Operations under the workspace scope, such as Saved SQL and Query, will need to carry workspaceId in params or request body, and you can find the ID in the workspace URL.

For example: https://web.default.myname.apps.cannerdata.com/workspaces/444e8753-a4c0-4875-bdc0-834c79061d56, where *444e8753-a4c0-4875-bdc0-834c79061d56 * is workspaceId

Errors

Common Errors are as follows.

  • status: 400, the user gives an incorrect parameter format, for example: limit in ?limit=some-string must be number.
  • status: 401, incorrect authentication information, so there is no permission to obtain the modified resource. For example, no Authorization header is included
  • status: 404, The given resource could not be found.

Service

GET /service/:service

Get service status.

Params

namedescription
serviceservice name, eg: SQL_ENGINE

Response

  • status: 200
    {
    status: string;
    lastUsed: iso string;
    id: string;
    service: string;
    maxIdleTime: number;
    }

PUT /service/:service

Update service status, for example: wake up a specific service.

Params

namedescription
serviceservice name, eg: SQL_ENGINE

Input

namedescription
statetrue, false, enable or disable the service.

Response

  • status: 200

Saved SQL

GET /sqls

Query String

namedescription
workspaceId-

Response

  • status: 200
    [
    {
    id: string;
    title: string;
    description?: string;
    sql: string;
    workspaceId: string;
    accountId: string;
    }
    ]

GET /sql/:id

Params

namedescription
idID of the Saved SQL

Query String

namedescription
workspaceId-

Response

  • status: 200
    {
    id: string;
    stats: {
    state: string;
    queued: boolean;
    scheduled: boolean;
    nodes: number,
    totalSplits: number,
    queuedSplits: number,
    runningSplits: number,
    completedSplits: number,
    cpuTimeMillis: number,
    wallTimeMillis: number,
    queuedTimeMillis: number,
    elapsedTimeMillis: number,
    processedRows: number,
    processedBytes: number,
    peakMemoryBytes: number,
    spilledBytes: number,
    };
    }

POST /sql

Save a new SQL code.

Input

namedescription
workspaceId-
sqlSQL code
descriptionThe SQL description for this store
titleThe displayed title of the stored SQL

Response

  • status: 200
    {
    id: string;
    title: string;
    description?: string;
    sql: string;
    workspaceId: string;
    }

POST /sql/:id

With Saved SQL, the system will return a Query Object.

Params

namedescription
idID of the Saved SQL

Input

namedescription
workspaceId-

Response

  • status: 200
    {
    id: string;
    statementId: string | null;
    accountId?: string | null;
    status?: 'QUEUED' | 'PLANNING' | 'RUNNING' | 'FINISHED' | 'FAILED';
    startedAt?: string;
    sql?: string;
    duration?: number;
    workspaceId: string;
    workspaceSqlName?: string;
    location?: string;
    error?: Record<string, any>;
    userId?: string;
    userType?: string;
    rowCount?: number;
    fromCache?: boolean;
    source?: Source;
    columns?: Array<Record<string, any>>;
    queryStats?: Record<string, any>;
    outputStage?: Record<string, any>;
    dataFormat?: DataFormat;
    }

Query

GET /queries

Query String

namedescription
workspaceId-
limitNumber of data returned
offsetNumber of data skipped

Response

  • status: 200
    {
    totalCount: number
    result: Array<{
    id: string;
    statementId: string | null;
    accountId?: string | null;
    status?: 'QUEUED' | 'PLANNING' | 'RUNNING' | 'FINISHED' | 'FAILED';
    startedAt?: string;
    sql?: string;
    duration?: number;
    workspaceId: string;
    workspaceSqlName?: string;
    location?: string;
    error?: Record<string, any>;
    userId?: string;
    userType?: string;
    rowCount?: number;
    fromCache?: boolean;
    source?: Source;
    columns?: Array<Record<string, any>>;
    queryStats?: Record<string, any>;
    outputStage?: Record<string, any>;
    dataFormat?: DataFormat;
    }>
    }

GET /query/:id

Query String

namedescription
idID of the Query

Params

namedescription
workspaceId-

Response

  • status: 200
    {
    id: string;
    statementId: string | null;
    accountId?: string | null;
    status?: 'QUEUED' | 'PLANNING' | 'RUNNING' | 'FINISHED' | 'FAILED';
    startedAt?: string;
    sql?: string;
    duration?: number;
    workspaceId: string;
    workspaceSqlName?: string;
    location?: string;
    error?: Record<string, any>;
    userId?: string;
    userType?: string;
    rowCount?: number;
    fromCache?: boolean;
    source?: Source;
    columns?: Array<Record<string, any>>;
    queryStats?: Record<string, any>;
    outputStage?: Record<string, any>;
    dataFormat?: DataFormat;
    }

GET /query/:id/result

Get the execution result of Query.

Params

namedescription
idID of the Query

Query String

namedescription
workspaceId-
limitNumber of data returned
offsetNumber of data skipped

Response

  • status: 200
    {
    result: any;
    columns: Record<string, any>[];
    rowCount: number;
    }

POST /query

Execute SQL

Input

namedescriptiontype
workspaceId-String
sqlSQL codeString
cacheRefreshWhether to refresh the CacheBoolean
cacheTTLCache Time-to-live (Cache retention time)Number

Response

  • status: 200
    {
    id: string;
    statementId: string | null;
    accountId?: string | null;
    status?: 'QUEUED' | 'PLANNING' | 'RUNNING' | 'FINISHED' | 'FAILED';
    startedAt?: string;
    sql?: string;
    duration?: number;
    workspaceId: string;
    workspaceSqlName?: string;
    location?: string;
    error?: Record<string, any>;
    userId?: string;
    userType?: string;
    rowCount?: number;
    fromCache?: boolean;
    source?: Source;
    columns?: Array<Record<string, any>>;
    queryStats?: Record<string, any>;
    outputStage?: Record<string, any>;
    dataFormat?: DataFormat;
    }

Sample code

import axios from 'axios';
import pRetry from 'p-retry';
import delay from 'delay';

const getData = async ({refresh = false, ttl, sql}) => {
const workspaceId = "9d5c99c3-71bd-4090-a5db-xxxxx";
const endpoint = "https://staging-xx-xxx.dev.apps.cannerdata.com/web/api/v1";
const token = "Y2xpZW50XzM3YzNiNDxxxx";

const client = axios.create({
baseURL: endpoint,
headers: {
Authorization: `Token ${token}`
}
});

// Make query
const {data} = await client.post('/query', {
workspaceId,
sql,
cacheRefresh: refresh,
cacheTTL: ttl
});

// Wait query to finish by checking the status
await pRetry(async () => {
const {data: queryStatus} = await client.get(`/query/${data.id}?workspaceId=${workspaceId}`);

// If status is not FINISHED or FAILED, check again after one second
if (queryStatus.status !== 'FINISHED' && queryStatus.status !== 'FAILED') {
await delay(1000);
throw new Error('not finished');
}

return queryStatus;
});

const {data: limitResult} = await client.get(`/query/${data.id}/result?workspaceId=${workspaceId}&limit=10000&offset=0`);
return limitResult.result;
}

const run = async () => {
console.time();
const data = await getData({
refresh: false,
ttl: 86400,
sql: 'select * from supplier_81391'
});
console.log(data);
console.timeEnd();
}

run().catch(console.error)

PUT /query/:id/cancel

Cancel the executing SQL Query

Query String

namedescription
idID of the Query

Input

namedescription
workspaceId-

Response

  • status: 200