[]
        
(Showing Draft Content)

Remote Read and Adapter

A remote table retrieves data through the read configuration.

The read option defines:

  • Where to request data

  • How to send the request

  • How to interpret the response structure

By default, the response is treated as a standard JSON array.

If the response follows a structured protocol, an adapter can be specified.

Basic HTTP Read (Default Behavior)

If no adapter is specified, the response is treated as the records array.

Example:

const products = dataManager.addTable("products", {
    remote: {
        read: {
            url: "https://example.com/api/products",
            method: "GET"
        }
    }
});

products.fetch();

Expected response format:

[
  { "ProductId": 1, "ProductName": "ItemA", "UnitPrice": 15 },
  { "ProductId": 2, "ProductName": "ItemB", "UnitPrice": 17 }
]

If the response is already an array, no adapter is required.

REST Adapter

Some REST APIs return a wrapped structure.

Example response:

{
  "status": "success",
  "data": [
    { "id": 1, "name": "Item A" },
    { "id": 2, "name": "Item B" }
  ]
}

Use the rest adapter to extract the data field:

const products = dataManager.addTable("products", {
    remote: {
        read: {
            url: "https://example.com/api/products",
            adapter: "rest"
        }
    }
});

With the REST adapter:

  • The data property is treated as the record collection.

  • Other wrapper properties are ignored.

OData Adapter

OData responses store records in the value property.

Example response:

{
  "@odata.context": "...",
  "value": [
    { "ProductId": 1, "ProductName": "ItemA" }
  ]
}

Use:

const products = dataManager.addTable("products", {
    remote: {
        read: {
            url: "https://example.com/api/products",
            adapter: "odata"
        }
    }
});

The adapter automatically extracts the value array.

OData v4 Adapter

OData v4 follows the same value structure but may include additional metadata.

const products = dataManager.addTable("products", {
    remote: {
        read: {
            url: "https://example.com/api/products",
            adapter: "odata4"
        }
    }
});

The odata4 adapter handles v4-specific metadata automatically.

GraphQL Adapter

GraphQL responses wrap records inside nested data objects.

Example response:

{
  "data": {
    "users": {
      "data": [
        { "id": "1", "name": "Leanne Graham" }
      ]
    }
  }
}

Example configuration:

const users = dataManager.addTable("users", {
    remote: {
        read: {
            url: "https://graphqlzero.almansi.me/api",
            adapter: "graphql",
            method: "POST",
            body: {
                query: `
                    query {
                        users {
                            data {
                                id
                                name
                                email
                            }
                        }
                    }
                `
            }
        }
    },
    schema: {
        dataPath: "users.data"
    }
});

Important:

  • GraphQL usually requires POST.

  • The query must be provided.

  • schema.dataPath specifies where the record array resides.

Schema details are documented in the Schema section.

Using Request Options

The options property corresponds to the standard fetch configuration.

Example:

read: {
    url: "https://example.com/api/products",
    method: "POST",
    options: {
        headers: {
            "Content-Type": "application/json"
        }
    }
}

This allows:

  • Custom headers

  • Credentials

  • Mode configuration

  • Other fetch settings

Using body

The body property is a simplified way to specify the request body.

Example:

read: {
    url: "https://graphqlzero.almansi.me/api",
    adapter: "graphql",
    method: "POST",
    body: {
        query: "{ users { data { id name } } }"
    }
}

If both body and options.body are provided:

  • body takes priority.

  • Operation-specific bodies may override it.

Custom Read Handler

Instead of providing a URL configuration, you can define a function:

const products = dataManager.addTable("products", {
    remote: {
        read: function () {
            return Promise.resolve([
                { ProductId: 1, ProductName: "Chai" }
            ]);
        }
    }
});

This allows:

  • Full control over data retrieval

  • Integration with custom transport layers

  • Mock implementations

Note:

Function-based handlers cannot be serialized during export.