Новые обновления в конце.
Мы создаем библиотеку BigQuery Storage в JavaScript для браузеров.
Проблема, с которой мы сталкиваемся, заключается в том, что мы получаем ошибка 404 из https://bigquerystorage.googleapis.com/
:
Это похоже на проблему CORS, но на самом деле это проблема 404:
$> curl 'https://bigquerystorage.googleapis.com/google.cloud.bigquery.storage.v1beta1.BigQueryStorage/CreateReadSession' \
-H 'x-goog-request-params: table_reference.project_id=project&table_reference.dataset_id=dataset' \
-H 'X-User-Agent: grpc-web-javascript/0.1' -H 'DNT: 1' -H 'Content-Type: application/grpc-web-text' \
-H 'Accept: application/grpc-web-text' -H 'X-Grpc-Web: 1' -H 'Sec-Fetch-Dest: empty' \
--data-binary 'ydG9k_binary_data_oATgB' --compressed
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
<title>Error 404 (Not Found)!!1</title>
...
Есть идеи, что происходит с запросом?
Вот все ресурсы, которые мы используем. Это базовая структура:
Исходные файлы .proto
получены из:
Для компиляции .proto
в .js
мы используем protoc
и плагин protoc-gen-grpc-web
с:
cd src/proto/
protoc -I=. $(find . -iname "*.proto") --js_out=import_style=commonjs:. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:.
И, наконец, это файл big_query_storage.js
, который мы связываем rollup.js
:
import BigQueryStorage from './proto/storage_grpc_web_pb.js';
import BigQueryStorageEnums from './proto/storage_pb.js';
import TableComponents from './proto/google/cloud/bigquery/storage/v1beta1/table_reference_pb.js';
import Timestamp from 'google-protobuf/google/protobuf/timestamp_pb.js';
const bigQueryStorageHostname = 'https://bigquerystorage.googleapis.com'
const projectId = 'project';
const datasetId = 'dataset';
const tableId = 'table';
const fields = ['column'];
const rowRestriction = 'where';
function BigQueryStorageTest() {
let client = new BigQueryStorage.BigQueryStorageClient(bigQueryStorageHostname);
let tableReference = new TableComponents.TableReference();
tableReference.setProjectId(projectId);
tableReference.setDatasetId(datasetId);
tableReference.setTableId(tableId);
let readOptions = new TableComponents.TableReadOptions();
readOptions.setSelectedFieldsList(fields);
readOptions.setRowRestriction(rowRestriction);
const parent = `projects/${projectId}`;
let readSessionRequest = new BigQueryStorage.CreateReadSessionRequest();
readSessionRequest.setTableReference(tableReference);
readSessionRequest.setParent(parent);
readSessionRequest.setReadOptions(readOptions);
readSessionRequest.setFormat(BigQueryStorageEnums.DataFormat.AVRO);
readSessionRequest.setShardingStrategy(BigQueryStorageEnums.ShardingStrategy.LIQUID);
let metadata = {};
let routingHeader = new URLSearchParams({
'table_reference.project_id': encodeURI(tableReference.getProjectId()),
'table_reference.dataset_id': encodeURI(tableReference.getDatasetId())
}).toString();
let routingMetadata = {
'x-goog-request-params': routingHeader
};
metadata = {...metadata, ...routingMetadata}
let session = client.createReadSession(readSessionRequest, metadata);
}
export default BigQueryStorageTest;
ОБНОВЛЕНИЕ 1:
Похоже, API хранилища больших запросов не поддерживает вызовы gRP C в текстовом режиме , В текстовом режиме заголовок Content-Type
устанавливается на application/grpc-web-text
, а тело в двоичном виде, закодированное в base64.
Таким образом, из-за этого API не может найти таблицу в закодированном теле, возвращая ошибку 404 .
Изменение скомпилированных файлов .js
(из .proto
) для использования двоичного файла в качестве формата, тело отправляется в виде двоичного файла, а заголовок Content-Type
устанавливается на application/x-protobuf
. Это работает, поскольку API не возвращает ошибку 404, но получено 400, Invalid resource field value in the request
.
ОБНОВЛЕНИЕ 2:
Существует новое хранилище BigQuery библиотека для Node.js https://github.com/googleapis/nodejs-bigquery-storage, которая работает как шарм в Node.js, очевидно, но имеет некоторые проблемы при портировании в браузеры.
Похоже, что это не может выполняет потоковые операции и выдает эту ошибку при доступе к сгенерированной заглушке для службы readRows
:
TypeError: undefined is not a function
at Service.newServiceStub.<computed> [as readRows] (fallback.js:190)
at big_query_storage_client.js:147
at streamingApiCaller.js:37
at timeout.js:43
at Object.request (streaming.js:102)
at makeRequest (index.js:128)
at retryRequest (index.js:96)
at StreamProxy.setStream (streaming.js:93)
at StreamingApiCaller.call (streamingApiCaller.js:53)
at createApiCall.js:72