Data Requests enable you to retrieve information from public API endpoints that do not require sensitive information like API keys. For APIs that do require keys, see Advanced: API-key Gated Data.
In this walkthrough, we'll use the SEDA Request Starter Kit, which includes all the necessary dependencies.
HTTP Fetch: GET
The httpFetch method is available only during the execution phase. Using it in the tally phase will trigger an error due to the non-deterministic nature of httpFetch. To make an HTTP request, we use the httpFetch method:
import { Console, httpFetch, OracleProgram } from"@seda-protocol/as-sdk/assembly";exportclassMyDataRequestextendsOracleProgram {execution():void {// Call the API swapi.dev and return an HttpResponse objectconstresponse=httpFetch("https://swapi.dev/api/planets/1");// Ensure the fetch call has succeededif (!response.ok) {Process.error(Bytes.fromUtf8String("Could not fetch API endpoint")); }Console.log(response.bytes.toUtf8String()); }tally():void {thrownewError("Not implemented"); }}newMyDataRequest().run()
Running this program with the following test will output the result of the execution, showing the httpFetch response as a string. You can place this test in tests/my-dr.test.ts:
import { describe, it} from"bun:test";import { file } from"bun";import { testOracleProgramExecution } from"@seda-protocol/dev-tools"describe("data request execution", () => {it("should run MyDataRequest",async () => {constwasmBinary=awaitfile("build/debug.wasm").arrayBuffer();// Locally executes the Data RequestconstvmResult=awaittestOracleProgramExecution(Buffer.from(wasmBinary),// This program doesn't have any inputsBuffer.from(""), );console.log(vmResult.stdout); });});
Running the test will compile the binary and execute the test file, showing the output of the API formatted in JSON.
Weโve successfully created an Oracle Program that fetches data. To make the program more useful, we need to parse the JSON response and work with its properties. The SEDA-SDK utilizes the json-as library, allowing you to define a schema and parse a JSON string into that schema. This library is already included in the starter kit.
Letโs modify our example to integrate this library:
import { Console, httpFetch, OracleProgram } from"@seda-protocol/as-sdk/assembly";// Annotate the class so that json-as can parse this@jsonclassPlanet {// ! required, since json-as sets these properties. name!:string; terrain!:string;}exportclassMyDataRequestextendsOracleProgram {execution():void {constresponse=httpFetch("https://swapi.dev/api/planets/1");// Parse the response bytes to our JSON schemaconstplanet=response.bytes.toJSON<Planet>();// Ensure the fetch call has succeededif (!response.ok) {Process.error(Bytes.fromUtf8String("Could not fetch API endpoint")); }Console.log(`We are on planet ${planet.name}, which is a ${planet.terrain} terrain`); }tally():void {thrownewError("Not implemented"); }}newMyDataRequest().run()
Now you can call any open API you want and process the data as needed.
HTTP Fetch: POST
The SEDA SDK enables you to send POST requests (as well as PATCH, PUT, and others) with an attached body. This allows you to work with various APIs, including GraphQL or uploading files to IPFS.
import { Bytes, Console, httpFetch, OracleProgram, Process } from"@seda-protocol/as-sdk/assembly";@jsonclassGraphQLQuery { query!:string;}exportclassMyDataRequestextendsOracleProgram {execution():void {constqueryBody=` query ExampleQuery { company { name } } `;constgraphQLQuery=newGraphQLQuery();graphQLQuery.query = queryBody;// httpFetch allows you to modify the request headersconstheaders=newMap<string,string>();headers.set('content-type','application/json');// Fetches the GraphQL API endpointconstresponse=httpFetch("https://spacex-production.up.railway.app/", { headers, method:"POST",// The body to send along with the request body:Bytes.fromJSON(graphQLQuery), });// Ensure the fetch call has succeededif (!response.ok) {Process.error(Bytes.fromUtf8String("Could not fetch API endpoint")); }Console.log(response.bytes.toUtf8String()); }tally():void {thrownewError("Not implemented"); }}newMyDataRequest().run()
Running the same test will give you the response of the POST request: