API is one of the most common solutions for data transmission and interaction between systems. This article describes how to create a new REST API 2.0 data connection.
Log in to BytePlus, navigate to a specific project, click Data Preparation, find Data Connection in the drop-down list, and click Data Connection.
Select REST API 2.0 on the page.
Log in to BytePlus, click Data Preparation --> Dataset, select the "Create" button in the upper left corner to create a new dataset.
When selecting a data connection, click Create Configuration.
The following steps are the same as steps 2 and 3 in Create via data connection. After completing the configuration, you will remain in the pop-up window for selecting a data connection for the dataset, and you can proceed directly to the next step of dataset creation.
Parameters | Configuration instructions |
|---|---|
Data connection name | Custom names are supported, or you can use the system default name (for example: REST_API_2.0_timestamp). |
URL address | Enter the complete URL of the API to be connected. Supports import and export of cURL. |
Request method | Supports two request methods: GET and POST.
|
OAuth2 authentication | Supports OAuth2 authorization code mode. warning Enable this feature when API requests need to access third-party service interfaces that use the OAuth2 authorization code flow. |
Parameter settings | Construct complete API request parameters, including request headers, request parameters, request body, pre-processing operations, and post-processing operations. |
Advanced settings | Supports configuration of timeout duration, number of retries, pagination, and more. |
Custom names are supported, or you can use the system default name (for example: REST_API_2.0_timestamp).
Enter the URL address of the API to connect to. The user can enter it manually or use cURL import to complete the URL address, request method, and parameter settings. For completed configurations, cURL format export is also supported.
tip
curl is a command-line tool used for transferring data over various network protocols, such as HTTP, HTTPS, FTP, and more. It supports sending requests and receiving responses, and can include parameters, authentication information, or file content. Example:
curl -X POST "https://api.example.com/import" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "name": "John Doe", "email": "john@example.com" }'
Supports two request methods: GET and POST.
Supports the OAuth2 authorization code mode.
warning
Enable this feature when an API request needs to access a third-party service interface that uses the OAuth2 authorization code flow.
warning
The parameter settings section guides users through a standardized process to configure the basic information for API requests, including request headers, request parameters, request body, as well as pre-processing and post-processing operations. The system provides built-in variables and built-in functions. For details, refer to System built-in variables and System built-in functions.
tip
The parameter value supports both static and dynamic values. The specific input specifications are as follows:
Supports configuring key and value, as well as add and delete operations, with up to 10 groups configurable.
Enter all query parameters required by the API.
Select the request body type (raw, form-data, or x-www-form-urlencoded); all support user input of a JSON-formatted request body.
General rule: When operating on JSON, $ represents the root node, and . represents accessing a child node.
If the JSON data is as follows:
{ "showapi_res_error": "", "showapi_res_id": "6597a2f5fb638cf45b4d460c", "showapi_res_code": 0, "showapi_fee_num": 1, "showapi_res_body": { "list": [ { "time": "14:26:57", "zhesuan": "193.69", "code": "AED", "hui_out": "195.91", "chao_in": "192.95", "chao_out": "199.47", "name": "阿联酋迪拉姆", "hui_in": "194.55", "day": "2024-01-05" }, { "time": "14:26:57", "zhesuan": "477.56", "code": "AUD", "hui_out": "481.77", "chao_in": "478.08", "chao_out": "483.16", "name": "澳大利亚元", "hui_in": "478.57", "day": "2024-01-05" } ], "listSize": 28, "ret_code": 0 } }
Then the values corresponding to some paths are as follows:
$.showapi_fee_num = 1 $.showapi_res_id = "6597a2f5fb638cf45b4d460c" $.showapi_res_body.list.* = [{"time":"14:26:57","zhesuan":"193.69" ... // Omitted below
To perform additional steps to prepare data or obtain necessary information before the main request, use this configuration.
warning
You can set up to 5 preceding operations.
Provides a more flexible and powerful way to configure custom parameters, supports Groovy syntax, and allows users to write code for multi-level request parsing. For rules on writing post-request actions, refer to Post-processing operation writing rules.
Allows users to set the request timeout, number of retries, pagination, and other options.
Parameter | Configuration description |
|---|---|
Timeout | The maximum time to wait for a response to an input request (unit: milliseconds). The default is 3 minutes. |
Retry count | When a request fails, the number of retry attempts the system will make, up to 5 times. |
Pagination | After enabling the pagination feature, configure as required. The termination condition is a Groovy expression. See Termination condition writing rules. warning
|
Pagination types include numeric pagination and cursor pagination:
Numeric pagination (for APIs with explicit page numbers) | Cursor pagination (for APIs without fixed page numbers) |
|---|---|
|
|
The following explains the relevant parameter configurations:
Parameters | Configuration instructions |
|---|---|
Starting page | Applicable to numeric pagination. Defines the starting page number for pagination requests, specifying from which page to begin retrieving data. |
Pagination parameter path | Applicable to cursor pagination. Points to the JSON path where the cursor is stored in the response (must be of Map or Array |
Request interval | Controls the time interval between consecutive pagination requests (unit: milliseconds) to prevent triggering API rate limits due to high-frequency requests. |
Maximum pagination | Limits the upper bound of total request attempts (to avoid infinite loops). The maximum page number for pagination is 10,000, with a default of 10. |
Termination condition | Supports writing Groovy expressions to implement termination conditions calculated from the current request. tip Two examples are provided below:
|
Limits for the number of fields, items per page, and pagination configuration:
Configuration items | Note | Configuration limits |
|---|---|---|
Number of fields | Total number of data fields to be processed | It is recommended to keep the number of fields within 150. |
Entries per page | Number of data entries displayed per page | It is recommended that the product of entries per page and number of fields be less than 10,000. The pagination size should take into account the interface's performance, number of fields, and data volume. |
Pagination page number | The maximum number of pages that can be requested (pagination stops if exceeded) | The maximum pagination page number is 10,000. |
Example:
For example, to end pagination when the data list in the request result is empty, and to set the maximum number of paginations as the upper limit of request attempts (default is 10, maximum is 10,000), configure as follows:
When in use, reference ${pageNum}. This variable starts from the initial page and continues until the termination condition is met.
tip
Parameters | Configuration instructions |
|---|---|
Parsing result | After completing basic information configuration, click Send request. The system will parse the request and display the parsing result here. |
Field path | The root path specified when parsing API request results, used to locate the data's position in the JSON structure (must be of Map or Array |
Field settings | The path of the final field obtained after parsing the root path, which is also the final field result for this data connection. |
Data preview | This section supports previewing the first 100 rows of detailed data for the currently selected field. |
After completing the above basic configuration steps, click "Send request" to have the system parse the request. The parsing order is "Pre-request action" > "Current request" > "Post-request action", and the "Parsing result" will be displayed.
After the system completes request parsing, the user also needs to configure the path, including setting the field path, configuring fields, and previewing data.
Enter the field path, using $ to represent the root node and a period (.) to indicate a child node. Click the "Get Fields" button. The system will parse and display the "Field Configuration" section.
This section configures the root path of the parsing result, with the following rules:
Example:
// Retrieve the entire result. The result fields include: showapi_res_error, showapi_res_id, ..., showapi_res_body $ // Retrieve the contents of the array $.showapi_res_body.list.* = [{"time":"14:26:57","zhesuan":"193.69" ... // The following is omitted
Use the "Add" button to create new fields. The parsing logic is based on the rootPath you entered to generate the result. You can also delete configured fields.
This section configures the path of the final fields obtained after parsing the root path, which is also the final field result of this data connection.
warning
For cases where the root path is an array, if the field path prefix is not consistent with the root path, the value corresponding to that field will be calculated and directly added to each element of the array in the final result set.
For example, for weather data, if the root path is $.forcast15days.list.*, which represents the weather for the next 15 days, and the user adds a $.city field to represent the city, then the value of $.city will be calculated and directly added to each future weather data entry as a key named city. The value will be the same for every item in the array.
Click the "Data Preview" button to view the first 100 rows of detail data for the currently selected field.
After all content is configured, click Test Connection to test the connectivity of the data source. After the test is successful, click Save to complete all configurations for the current data connection.
Both dynamic parameters and post-processing scripts use Groovy as the script engine.
For ${} appearing in params, body, header, or url, it is executed as a Groovy string interpolation expression to obtain the result. Some custom functions are also built in, such as the md5() method, date variables, and more. Below are some examples of execution results:
假如目前有两个参数,是在前置请求中配置好的,如下: num1 = 1 num2 = 2 则${}里面的内容会被作为表达式执行,其余部分为普通字符串,下面表达式结果分别为: abc // abc ${num1} // 1 ${num1+num2} // 3 ${num1}+num2 // 1+num2 ${num3} // Error: parameter num3 is missing ${"${num1}"} // ${num1}
The post-processing operation example is as follows:
def convertJson(response) { /*Enter post-processing code hereresponse represents the result returned by the API. Suppose the API returns the following result {"city": "上海市", "forcast": [ {"temperature": 5, "day": "2024-01-01"}, {"temperature": 6, "day": "2024-01-02"}, ], "test": "test" }Some code examples:Scenario 1: Add, edit, and loop to add city to each element in the list ls = response.forcast for (i=0; i< ls.size(); i++) { ls[i].city = response.city }Scenario 2: Remove a specific key response.remove("test") */ return response; }
Groovy syntax is supported. When the termination condition is met, the next page will not be accessed. response represents the result of this request. Example:
response.data.size() == 0 // Stop pagination when the length of the data list under response is 0 (empty list) response.hasMore == false // Stop pagination when hasMore under response is false
The following dynamic parameters are built into the system. When naming variables, avoid using the same names as system variables; otherwise, they will be overwritten.
Scope: url, header, params, body. Not valid in post-processing operations.
${date} // Date, format: yyyyMMdd ${DATE} // Date, format: yyyy-MM-dd ${hour} // Hour, format: HH ${HOUR} // Hour, format: H ${year} // Year, format: yyyy ${month} // Month, format: MM ${day} // Day, format: dd ${timestamp} // Timestamp, format: 13-digit timestamp ${last_date} // Last day of the previous month, format: yyyyMMdd ${last_DATE} // Last day of the previous month, format: yyyy-MM-dd ${last_day} // Last day of the previous month, format: dd 以上变量支持日期加减,例如 ${date-1},代表前一天
Scope: url, header, params, body, post-processing operations.
tip
You can use the free API debugging tool for testing.
Add md5 value and current system timestamp in the URL
Add a value calculated by a complex expression in the request header
String md2Hex(String data); String md5Hex(String data); String shaHex(String data); String sha1Hex(String data); String sha256Hex(String data); String sha384Hex(String data); String sha512Hex(String data); byte[] md2(String data) byte[] md5(String data) byte[] sha(String data) byte[] sha1(String data) byte[] sha256(String data) byte[] sha384(String data) byte[] sha512(String data)
java.lang.Math all related functions
// format: Format date as a string. currentDate = new Date() formattedDate = currentDate.format('yyyy-MM-dd HH:mm:ss') // plus and minus: Add or subtract dates. tomorrow = currentDate + 1 yesterday = currentDate - 1
// capitalize(): Capitalize the first character of a string. str = "groovy" str.capitalize() // Output: "Groovy" // reverse(): Reverse a string. str.reverse() // Output: "yvoorg" // contains(): Check if a string contains a specified substring. str.contains("oo") // Output: true // toInteger(), toLong(), toFloat(), toDouble(): Convert a string to the corresponding numeric type. str = "123" str.toInteger() // Output: 123 // split(): Split a string. str = "a,b,c" str.split(",") // Output: ["a", "b", "c"] // isNumber(): Check if a string is a number. str.isNumber() // Output: true
// each: Execute a closure operation on each element of a collection. list = [1, 2, 3] list.each { println it } // Output: 1 2 3 // findAll: Filter elements in the collection that meet the criteria. list = [1, 2, 3, 4, 5] evens = list.findAll { it % 2 == 0 } println evens // Output: [2, 4] // collect: Map each element in the collection to another value. list = [1, 2, 3] squares = list.collect { it * it } println squares // Output: [1, 4, 9] // sum: Calculate the sum of all elements in the collection. list = [1, 2, 3] println list.sum() // Output: 6 // join: Join the elements in the collection into a string using the specified separator. list = ["a", "b", "c"] println list.join("-") // Output: "a-b-c"
// each: Execute a closure operation on each entry in the Map. map = [a: 1, b: 2, c: 3] map.each { key, value -> println "$key: $value" } // Output: a: 1 b: 2 c: 3 // findAll: Filter entries in the Map that meet the criteria. map = [a: 1, b: 2, c: 3] filtered = map.findAll { key, value -> value > 1 } println filtered // Output: [b: 2, c: 3] // collect: Map each entry in the Map to another value. map = [a: 1, b: 2, c: 3] collected = map.collect { key, value -> "$key=$value" } println collected // Output: ["a=1", "b=2", "c=3"] // getOrDefault(Object key, Object defaultValue): Get the value for the specified key; if the key does not exist, return the default value. map = [a: 1, b: 2] println map.getOrDefault('c', 0) // Output: 0 // collectEntries(Closure closure): Convert the Map to another Map. map = [a: 1, b: 2, c: 3] newMap = map.collectEntries { key, value -> [(key): value * 2] } println newMap // Output: [a: 2, b: 4, c: 6] // find(Closure closure): Find the first entry in the Map that meets the criteria. map = [a: 1, b: 2, c: 3] entry = map.find { key, value -> value > 1 } println entry // Output: [b:2] or [c:3] // keySet(): Get all keys in the Map. map = [a: 1, b: 2, c: 3] println map.keySet() // Output: [a, b, c] // values(): Get all values in the Map. map = [a: 1, b: 2, c: 3] println map.values() // Output: [1, 2, 3] // flatten(): Flatten a nested Map. map = [a: [b: 2, c: 3], d: 4] println map.flatten() // Output: [a.b:2, a.c:3, d:4]
// unique(): Remove duplicate elements from the list. list = [1, 2, 2, 3, 4, 4] println list.unique() // Output: [1, 2, 3, 4] // sort(): Sort the list. list = [3, 1, 4, 1, 5, 9] println list.sort() // Output: [1, 1, 3, 4, 5, 9] // flatten(): Flatten a nested list into a single list. list = [1, [2, 3], [4, [5, 6]]] println list.flatten() // Output: [1, 2, 3, 4, 5, 6] // count(Closure closure): Count the number of elements that meet the criteria. list = [1, 2, 3, 4, 5] println list.count { it % 2 == 0 } // Output: 2
// step(int step): Iterate over the elements in the range with the specified step size. range = 1..10 range.step(2).each { println it } // Output: 1 3 5 7 9 // containsWithinBounds(Object value): Check whether the value is within the range (including boundaries). range = 1..10 println range.containsWithinBounds(10) // Output: true // subList(int fromIndex, int toIndex): Get the sublist within the specified index range. range = 1..10 println range.subList(2, 5) // Output: [3, 4, 5] // toList(): Convert the range to a list. range = 1..5 println range.toList() // Output: [1, 2, 3, 4, 5]
// Base64 encoding and decoding // Encoding str = "hello world" encoded = str.bytes.encodeBase64().toString() println "Base64 Encoded: $encoded" // Output: Base64 Encoded: aGVsbG8gd29ybGQ= // Decoding encoded = "aGVsbG8gd29ybGQ=" decoded = new String(encoded.decodeBase64()) println "Base64 Decoded: $decoded" // Output: Base64 Decoded: hello world
// MD5 str = "hello world" md5Hex = str.md5() println "MD5: $md5Hex" // Output: MD5: 5eb63bbbe01eeed093cb22bb8f5acdc3 // SHA-1 str = "hello world" sha1Hex = str.digest("SHA-1") println "SHA-1: $sha1Hex" // Output: SHA-1: 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed // SHA-256 str = "hello world" sha256Hex = str.digest("SHA-256") println "SHA-256: $sha256Hex" // Output: SHA-256: b94d27b9934d3e08a52e52d7da7dabfac484eefc56bf5ef4b102e3d8fdedfb68