Native query
raw SQL またはその他の database-specific query を database に対して直接実行します。
Native Query を使用する理由
Squid Client SDK には強力な query 機能がありますが、一部の operation では標準 query API で利用できない database-specific feature が必要です。たとえば SQL subselect、複雑な aggregation、stored procedure、MongoDB aggregation pipeline などです。Native query を使用すると、こうした advanced capability が必要な場合に database connector に対して raw query を直接実行できます。
概要
Native query は Squid の query abstraction を bypass し、database に対して直接実行されます。Squid は 3 種類の native query をサポートしています。
executeNativeRelationalQueryを使用する、SQL database(PostgreSQL、MySQL、ClickHouse、MS SQL Server)向けのrelational queryexecuteNativeMongoQueryを使用する、MongoDB connector 向けのMongoDB queryexecuteNativeElasticQueryを使用する、Elasticsearch connector 向けのElasticsearch query
3 つの method はすべて、query を実行する database の connector ID を必要とします。connector ID は Squid Console の connectors section で確認できます。
コアコンセプト
Native relational query
SQL database connector を使用している場合、database の connector ID と SQL query を渡して executeNativeRelationalQuery method を使用することで、raw SQL を実行できます。
次の例では、parameterized value を使用して native SQL query を実行します。
async function runNativeQuery(queryParam: string): Promise<any> {
const response = await this.squid.executeNativeRelationalQuery(
'DATABASE_CONNECTOR_ID',
'SELECT * FROM SQUIDS WHERE YEAR = ${year}',
{ year: queryParam }
);
return response;
}
native query を保護するには、Squid backend 内の Squid Service function を使用します。詳細については、data access の保護に関する documentationを参照してください。
Native MongoDB query
executeNativeMongoQuery method は、指定された parameter を使用して native MongoDB aggregation pipeline を実行し、result を含む promise を返します。
次の例では、Mongo aggregation pipeline を実行します。
async function countDocuments(): Promise<any> {
const response = await this.squid.executeNativeMongoQuery(
'DATABASE_CONNECTOR_ID',
'COLLECTION_NAME',
[{ $count: 'totalApplications' }]
);
return response;
}
Native Elasticsearch query
executeNativeElasticQuery method は、Elasticsearch query DSL で記述された request body を index に送信します。endpoint と HTTP method も optional に受け入れます(default: _search および GET)。
const result = await squid.executeNativeElasticQuery('DATABASE_CONNECTOR_ID', 'articles', {
query: { match: { title: 'observability' } },
size: 10,
});
native Elasticsearch query は、_search、_count、_msearch、_mget、_mapping、_sql、_eql などの read-only endpoint に制限されます。mutation を行う endpoint への request は error を返します。connector setup と Elasticsearch 固有の limit については、Elasticsearch connectorを参照してください。
Error Handling
| Error | 原因 | 解決策 |
|---|---|---|
| Invalid connector ID | connector ID が構成済みの database connector と一致しない | Squid Console の connectors section で connector ID を確認する |
| SQL syntax error | raw SQL query に無効な syntax が含まれる | まず database に対して query を直接 test し、typo と dialect-specific syntax を確認する |
| Invalid aggregation pipeline | MongoDB pipeline に無効な stage または operator が含まれる | MongoDB aggregation documentation を参照する |
| Mutating Elasticsearch endpoint | executeNativeElasticQuery が write endpoint を対象にした | native Elasticsearch query は read-only です。_search、_count、_sql などの endpoint を使用する |
| Security rule rejection | query が security rules により block された | user が permission を持つことを確認するか、backend の executable から native query を実行する |
ベストプラクティス
-
SQL injection を防ぐために、parameterized query を使用します。string concatenation ではなく parameter object を通じて value を渡します。
Client code// Recommended: parameterized query
const response = await this.squid.executeNativeRelationalQuery(
'CONNECTOR_ID',
'SELECT * FROM users WHERE name = ${name}',
{ name: userInput }
);
// Avoid: string concatenation (vulnerable to injection)
const response = await this.squid.executeNativeRelationalQuery(
'CONNECTOR_ID',
`SELECT * FROM users WHERE name = '${userInput}'`
); -
query logic と credential を server 上に保持するため、sensitive な native query は client から直接実行するのではなく、backend executable から実行します。executablesを参照してください。
-
ユースケースをサポートしている場合は、標準 query API を優先します。native query は Squid の query abstraction、real-time subscription、type safety を bypass します。
-
実行できる query を制御するため、backend security rule で native query を保護します。data access の保護を参照してください。