superset makeApi 源码

  • 2022-10-20
  • 浏览 (229)

superset makeApi 代码

文件路径:/superset-frontend/packages/superset-ui-core/src/query/api/v1/makeApi.ts

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import rison from 'rison';
import {
  SupersetClient,
  Payload as SupersetPayload,
  JsonObject,
  JsonValue,
  ParseMethod,
  Endpoint,
  Method,
  RequestBase,
} from '../../../connection';
import handleError, { ErrorInput } from './handleError';
import {
  SupersetApiRequestOptions,
  SupersetApiErrorPayload,
  ParsedResponseType,
} from './types';

const validRequestTypes = new Set(['form', 'json', 'search', 'rison']);

interface SupersetApiFactoryOptions extends Omit<RequestBase, 'url'> {
  /**
   * API endpoint, must be relative.
   */
  endpoint: Endpoint;
  /**
   * Request method: 'GET' | 'POST' | 'DELETE' | 'PUT' | ...
   */
  method: Method;
  /**
   * How to send the payload:
   *  - form: set request.body as FormData
   *  - json: as JSON string with request Content-Type header set to application/json
   *  - search: add to search params
   */
  requestType?: 'form' | 'json' | 'search' | 'rison';
}

function isPayloadless(method?: Method) {
  return (
    !method || method === 'GET' || method === 'DELETE' || method === 'HEAD'
  );
}

/**
 * Generate an API caller with predefined configs/typing and consistent
 * return values.
 */
export default function makeApi<
  Payload = SupersetPayload,
  Result = JsonObject,
  T extends ParseMethod = ParseMethod,
>(
  options: SupersetApiFactoryOptions & {
    /**
     * How to parse response, choose from: 'json' | 'text' | 'raw'.
     */
    responseType?: T;
    /**
     * Further process parsed response
     */
    processResponse?(result: ParsedResponseType<T>): Result;
  },
) {
  const {
    endpoint,
    method,
    requestType: requestType_,
    responseType,
    processResponse,
    ...requestOptions
  } = options;
  // use `search` payload (searchParams) when it's a GET request
  const requestType =
    requestType_ || (isPayloadless(method) ? 'search' : 'json');
  if (!validRequestTypes.has(requestType)) {
    throw new Error(
      `Invalid request payload type, choose from: ${[...validRequestTypes].join(
        ' | ',
      )}`,
    );
  }

  async function request(
    payload: Payload,
    { client = SupersetClient }: SupersetApiRequestOptions = {
      client: SupersetClient,
    },
  ): Promise<Result> {
    try {
      const requestConfig = {
        ...requestOptions,
        method,
        endpoint,
      };
      if (requestType === 'search') {
        requestConfig.searchParams = payload;
      } else if (requestType === 'rison') {
        requestConfig.endpoint = `${endpoint}?q=${rison.encode(payload)}`;
      } else if (requestType === 'form') {
        requestConfig.postPayload = payload;
      } else {
        requestConfig.jsonPayload = payload;
      }

      let result: JsonValue | Response;
      const response = await client.request({
        ...requestConfig,
        parseMethod: 'raw',
      });

      if (responseType === 'text') {
        result = await response.text();
      } else if (responseType === 'raw' || responseType === null) {
        result = response;
      } else {
        result = await response.json();
        // if response json has an "error" field
        if (result && typeof result === 'object' && 'error' in result) {
          return handleError(result as SupersetApiErrorPayload);
        }
      }
      const typedResult = result as ParsedResponseType<T>;
      return (
        processResponse ? processResponse(typedResult) : typedResult
      ) as Result;
    } catch (error) {
      return handleError(error as ErrorInput);
    }
  }

  request.method = method;
  request.endpoint = endpoint;
  request.requestType = requestType;

  return request;
}

相关信息

superset 源码目录

相关文章

superset handleError 源码

superset index 源码

superset types 源码

0  赞