Data Views API

circle-check

The Data Views API enables fine-grained access control over JSON resources in ESS through GraphQL-based filtering. Data subjects can create filtered "View Resources" that expose only specific fields from their source data, allowing selective sharing without exposing sensitive information.

Overview

Up to ESS 2.6, access control was available only at the resource level using Access Control Policies (ACP) or Access Grants. If a resource owner wanted to share specific fields from a resource while keeping other fields private, they had to manually create separate resources for each sharing scenario. This approach makes data harder to manage and can lead to synchronization issues.

The Data Views API solves this problem by introducing View Resources - dynamic resources that present filtered views of source data. View Resources behave like regular Solid resources but their content is automatically derived from other resources (Source Resources) using GraphQL queries. When source data changes, View Resources update automatically.

Key Benefits

  • Fine-grained sharing: Share specific fields from resources without creating duplicates

  • Automatic synchronization: View Resources update when source data changes

  • Reusable filters: View Definitions can be applied to multiple resources

  • Standard Solid integration: View Resources work with existing ACP, Access Grants, and Notifications

  • Audit support: View operations generate audit events like regular resources

Use Cases

  • Personal Data Sharing: Share contact information (name and email) while keeping phone numbers and addresses private

  • Business Data: Share transaction amounts and categories while hiding account numbers and merchant details

  • Collaborative Workflows: Share project status information while keeping internal notes and budgets confidential

Core Concepts

View Definition

A View Definition is a shareable resource that defines how to filter JSON data using GraphQL. It consists of:

  • GraphQL Schema: Defines the structure and fields available in the source data

  • GraphQL Query: Specifies which fields to include in the view

  • Metadata: Name, description, and purpose of the view

View Definitions are stored in a registry and can be reused across multiple resources. They're idempotent by name - creating a View Definition with the same name and content returns the existing definition.

Source Resource and Source Container

  • Source Resource: A regular Solid JSON resource that contains the original data

  • Source Container: A regular Solid container with JSON resources

Source Resources are protected while View Bindings exist - attempting to delete a Source Resource with active bindings returns a 409 Conflict error.

View Binding

A View Binding connects a View Definition to Source Resource(s) and specifies where to create the View Resource(s). There are two types:

  • VIEW_RESOURCE: Filters a single Source Resource, creating one View Resource at an explicit destination URI

  • VIEW_CONTAINER: Filters all JSON resources in a Source Container, creating View Resources in a destination container with matching relative paths

View Bindings are asynchronous - View Resources are created shortly after the binding (typically within 10 seconds).

View Resource and View Container

  • View Resource: A dynamic, read-only resource containing filtered JSON data from a Source Resource

  • View Container: A container of View Resources created from a Source Container

View Resources automatically update when source data changes. They can be shared using ACP or Access Grants like regular resources, and support notifications for change tracking.

Relationship Diagram

Data Views Endpoints

By default, the Data Views Service runs from the following root URL:

The Data Views API consists of the following endpoints:

Endpoint
Description

POST /views/registry

Create a new View Definition

GET /views/registry

List all View Definitions (paginated)

GET /views/registry/{id}

Retrieve a specific View Definition

DELETE /views/registry/{id}

Delete a View Definition

POST /views/bindings

Create a View Binding (VIEW_RESOURCE or VIEW_CONTAINER)

POST /views/bindings/preview

Preview filtered data without creating a binding (VIEW_RESOURCE only)

DELETE {viewResource}

Delete a View Resource and its binding

View Registry Endpoints

Create View Definition

Creates a new View Definition in the registry. View Definitions are idempotent by name - submitting the same name with identical content returns the existing definition (201 Created). Submitting the same name with different content returns a conflict error (409).

Input

Field
Value

Endpoint

https://storage.{ESS Domain}/views/registry

Method

POST

Authorization

Access token (DPoP or Bearer) with registry authorization

Content-Type

application/json

Payload

View Definition object

View Definition Structure

Field
Description

type

Required. The query type. Currently only "graphql" is supported (case-insensitive).

name

Required. Human-readable name for the View Definition. Used for idempotency - definitions with the same name and content are deduplicated.

schema

Required. GraphQL Schema Definition Language (SDL) defining the structure of the source data. Must be valid GraphQL SDL syntax.

query

Required. GraphQL query string specifying which fields to include in the view. Must be compatible with the provided schema.

description

Optional. Detailed description of what the View Definition does and its intended use.

purpose

Optional. Short identifier for the View Definition's purpose (e.g., "contact-sharing", "privacy", "reporting").

Example Request

Output

Returns 201 Created with a Location header pointing to the new View Definition URI. The response body contains the complete View Definition including its unique identifier.

Example Response

Validation Rules

  • Schema validation: The GraphQL schema must be valid SDL syntax. Invalid syntax returns 400 Bad Request.

  • Query validation: The GraphQL query must be syntactically correct and compatible with the schema. References to fields not in the schema return 400 Bad Request.

  • Security limits: Queries exceeding maximum depth or complexity limits return 400 Bad Request (see Configuration section).

  • Idempotency: Same name + same content returns existing definition (201 Created with existing URI).

  • Name conflicts: Same name + different content returns 409 Conflict.

circle-exclamation

List View Definitions

Retrieves a paginated list of all View Definitions in the registry. Any authenticated user can list View Definitions.

Input

Field
Value

Endpoint

https://storage.{ESS Domain}/views/registry

Method

GET

Authorization

Access token (DPoP or Bearer) - any authenticated user

Query Parameters

cursor (optional): Pagination cursor for next page

Example Request

Output

Returns 200 OK with a paginated list of View Definitions.

Example Response

Pagination

Field
Description

definitions

Array of View Definition objects for the current page.

hasMore

Boolean indicating if more pages are available.

nextCursor

Opaque cursor string to retrieve the next page. Only present when hasMore is true.

size

Number of definitions in the current page.

To retrieve the next page, include the cursor query parameter:

Retrieve View Definition

Retrieves a specific View Definition by its URI. Any authenticated user can retrieve View Definitions.

Input

Field
Value

Endpoint

https://storage.{ESS Domain}/views/registry/{definitionId}

Method

GET

Authorization

Access token (DPoP or Bearer) - any authenticated user

Example Request

Output

Returns 200 OK with the View Definition, or 404 Not Found if the definition doesn't exist.

Example Response

Delete View Definition

Deletes a View Definition from the registry. Any agent on the registry authorization allow-list can delete View Definitions (requires registry authorization).

circle-info

Existing Bindings Not Affected

When a View Binding is created, it copies the View Definition's schema and query. Deleting a View Definition from the registry does not affect existing bindings that reference it - those bindings will continue to work with their copied definitions.

Input

Field
Value

Endpoint

https://storage.{ESS Domain}/views/registry/{definitionId}

Method

DELETE

Authorization

Access token (DPoP or Bearer) with registry authorization

Example Request

Output

Returns 204 No Content on successful deletion.

Example Response

View Bindings Endpoints

Preview View Binding

Allows you to test a View Binding before creating it by returning the filtered data immediately. This is useful for validating that your View Definition produces the expected output.

circle-info

VIEW_RESOURCE Only

Preview is only available for VIEW_RESOURCE bindings. Attempting to preview a VIEW_CONTAINER binding returns 400 Bad Request. For VIEW_CONTAINER, create the binding and inspect individual View Resources after async processing completes.

Input

Field
Value

Endpoint

https://storage.{ESS Domain}/views/bindings/preview

Method

POST

Authorization

Access token (DPoP or Bearer) with data subject permission for the Source Resource's storage

Content-Type

application/json

Payload

View Binding request object

Example Request

Output

Returns 200 OK with the filtered JSON data, or 400 Bad Request for validation errors.

Example Response

Assuming the Source Resource contains:

The preview response would be:

Create View Binding

Creates a View Binding that connects a View Definition to Source Resource(s) and produces View Resource(s) at the specified destination. There are two types of View Bindings: VIEW_RESOURCE and VIEW_CONTAINER.

Input

Field
Value

Endpoint

https://storage.{ESS Domain}/views/bindings

Method

POST

Authorization

Access token (DPoP or Bearer) with data subject permission for the Source Resource's storage

Content-Type

application/json

Payload

View Binding object

View Binding Types Comparison

Aspect

VIEW_RESOURCE

VIEW_CONTAINER

Purpose

Filter a single Source Resource

Filter all JSON resources in a container

Source URI

Must NOT end with /

Must end with / (container)

Destination URI

Must NOT end with /

Must end with / (container)

Result

One View Resource at explicit URI

Multiple View Resources with matching relative paths

Preview Support

Yes, via /bindings/preview

No preview available

Data Matching

N/A (single resource)

Only creates views for data that produces non-empty results

VIEW_RESOURCE Binding Structure

Field
Description

type

Required. Must be "VIEW_RESOURCE".

definitionUri

Required. URI of the View Definition to apply. Must be a valid, existing View Definition in the registry.

sourceResource

Required. URI of the source JSON resource to filter. Must NOT end with /. Must be a resource you have data subject permission for.

destinationResource

Required. URI where the View Resource will be created. Must NOT end with /. Can be any valid URI in your storage.

Example VIEW_RESOURCE Request

Example VIEW_RESOURCE Response

VIEW_CONTAINER Binding Structure

Field
Description

type

Required. Must be "VIEW_CONTAINER".

definitionUri

Required. URI of the View Definition to apply to all matching resources in the Source Container.

sourceResource

Required. URI of the Source Container. Must end with /. All JSON resources in this container and its subcontainers will be processed.

destinationResource

Required. URI of the destination container where View Resources will be created. Must end with /. View Resources will maintain the same relative path structure as Source Resources.

Example VIEW_CONTAINER Request

Example VIEW_CONTAINER Response

VIEW_CONTAINER Path Structure

When a VIEW_CONTAINER binding is created, View Resources are created with the same relative paths as their Source Resources:

circle-info

Asynchronous Processing

View Binding creation is asynchronous. The API returns 201 Created immediately, but View Resources are materialized shortly afterward (typically within 10 seconds). Use retry logic when accessing View Resources to account for processing time. See Asynchronous Processing for details.

Idempotency

View bindings are idempotent by destination, definition, and source. Submitting the same binding request multiple times succeeds (201 Created) and references the same view resource.

Delete View Resource

Deletes a View Resource and its corresponding binding. If there are no more bindings on the associated Source Resource, this also removes its protection, allowing it to be deleted.

Input

Field
Value

Endpoint

{viewResourceUri}

Method

DELETE

Authorization

Access token (DPoP or Bearer) with write permission for the View Resource

Example Request

Output

Returns 204 No Content on successful deletion.

Example Response

GraphQL Query Features

The Data Views API uses GraphQL to define how source data is filtered. This section explains the supported GraphQL features for creating View Definitions.

Supported Data Types

Standard Scalars

GraphQL's standard scalar types are fully supported:

  • String: Text values

  • Int: 32-bit integer values

  • Float: Floating-point numeric values

  • Boolean: True or false values

  • ID: Unique identifier values (treated as strings)

Extended Scalars

Data Views supports additional scalar types for common data formats:

  • DateTime: ISO-8601 formatted date-time values (e.g., "2024-03-15T10:30:00.000Z")

  • Json: Arbitrary JSON objects or arrays

Extended scalars must be declared in the schema:

Field Selection

The simplest use of GraphQL is selecting specific fields from source data.

Basic Field Selection

Schema:

Query:

Source Data:

View Result:

Nested Object Selection

Schema:

Query:

Source Data:

View Result:

Array Field Selection

Schema:

Query:

Source Data:

View Result:

Query Filters

GraphQL filters allow you to select specific items from arrays based on conditions. Filters are specified as arguments to fields.

Equality Filters

Filter array items where a field equals a specific value:

Schema:

Query:

Source Data:

View Result:

Numeric Comparison Filters

Filter numeric fields using comparison operators:

Operator
Description

eq

Equal to

gt

Greater than

gte

Greater than or equal to

lt

Less than

lte

Less than or equal to

Schema:

Query (transactions over $100):

Source Data:

View Result:

Query (transactions between $50 and $200):

Array Membership Filters

Filter items where a field value is in a specified set.

Schema:

Query:

Source Data:

View Result:

Date Range Filters

Filter DateTime fields using temporal comparisons:

Operator
Description

after

DateTime is after (exclusive) the specified value

before

DateTime is before (exclusive) the specified value

Schema:

Query (March 2024 transactions):

Source Data:

View Result:

Multiple Filter Combination

Multiple filters on the same field are combined with AND logic.

Schema:

Query (Acme Inc purchases over $100 in March 2024):

All specified filters must match for a transaction to be included in the View.

Complete Workflows

Workflow 1: Basic Contact Filtering (VIEW_RESOURCE)

This workflow demonstrates creating a filtered View of a single resource containing personal contact information.

Step 1: Create Source Resource

Create a JSON resource with complete contact information:

Response:

Step 2: Create View Definition

Create a View Definition that filters to only name and email. Note that the schema only needs to define the fields used in the query - it doesn't need to include all fields from the Source Resource:

Response:

Step 3: Preview the Binding (Optional)

Test the View Definition before creating the binding:

Response:

The preview confirms that phone, address, and ssn are filtered out as expected.

Step 4: Create View Binding

Create the binding to produce the View Resource:

Response:

Step 5: Access View Resource

Access the View Resource (with retry for async processing):

Initial response (if processing not complete):

Retry after a few seconds.

Response (after processing completes):

Step 6: Share View Resource

Now you can share the View Resource using ACP or Access Grants. External users will only see name and email. They will never see the phone, address, or SSN fields from the Source Resource.

Step 7: Update Source Resource

Update the Source Resource with new data:

Response:

Step 8: View Auto-Updates

After a short delay, the View Resource automatically reflects the changes:

Response:

The View Resource updated automatically. Note that phone and address changes are not visible in the view.

Step 9: Delete View Binding

To stop sharing and remove the View Resource:

Response:

After a short delay, the View Resource is deleted and accessing it returns 404 Not Found. The Source Resource remains unchanged and can now be deleted if needed.

Workflow 2: Bulk Transaction Filtering (VIEW_CONTAINER)

This workflow demonstrates creating filtered Views of multiple resources in a container.

Step 1: Create Source Container

Create a container for transaction records:

Response:

Step 2: Add Transaction Resources

Add multiple transaction records to the container.

January Transactions:

February Transactions:

Responses:

Step 3: Create View Definition for Transactions

Create a View Definition that filters out account numbers:

Response:

Step 4: Create VIEW_CONTAINER Binding

Create a Binding for the entire container:

Response:

Step 5: Access View Resources

After async processing completes, access the filtered View Resources:

January View:

Response:

February View:

Response:

Note that accountNumber is filtered out from all View Resources.

Step 6: Add New Source Resource

Add a new transaction file to the Source Container:

Response:

Step 7: New View Auto-Created

After async processing, a View Resource is automatically created for the new file:

Response:

Step 8: Delete Source Resource

Delete one of the Source Resources:

Response:

Step 9: Corresponding View Auto-Deleted

After async processing, the corresponding View Resource is automatically deleted:

Response:

The other View Resources (2024-02.json and 2024-03.json) remain available.

Key Behaviors and Constraints

Asynchronous Processing

circle-exclamation

Typical Processing Times

  • View Resource creation: 5-15 seconds after binding creation

  • View Resource updates: 5-15 seconds after Source Resource changes

  • View Resource deletion: 5-15 seconds after binding deletion

Actual times depend on system load and data size.

circle-info

Client Retry Logic

Due to the asynchronous nature of View Resource creation and deletion, clients should implement retry logic when accessing newly created View Resources or verifying deletion completion.

Source Protection

triangle-exclamation

Protected Deletion Example - VIEW_RESOURCE

Response (when View Binding exists):

Protected Deletion Example - VIEW_CONTAINER

When a VIEW_CONTAINER binding exists for https://storage.example.com/alice/transactions/:

Attempting to delete the Source Container (BLOCKED):

Response:

Deleting a nested child resource (ALLOWED):

Response:

The nested child resource is deleted successfully, and the corresponding View Resource at /alice/views/transactions/2024-01.json is automatically deleted asynchronously.

Discovering View Bindings

To identify View Bindings on a Source Resource, inspect the Link headers in the resource's HTTP response. Source Resources with active bindings include a Link header with the relation type https://w3id.org/inrupt/namespace/vocab/storage/hasViewResource.

Example Request:

Example Response:

In this example, the Source Resource has two View Bindings pointing to:

  • https://storage.example.com/alice/shared/contact-view

  • https://storage.example.com/alice/public/basic-info

These URIs identify the View Resources that must be deleted before the source can be deleted.

Resolution

To delete a protected Source Root Resource or Container:

  1. Discover View Bindings: Inspect the Link headers on the Source Resource to identify all View Resources

  2. Delete each View Resource: Send DELETE requests to each View Resource URI (which deletes the binding)

  3. Delete the source: Once all bindings are removed, delete the source root resource or container

Step 1: Discover bindings

Response shows two View Bindings in the Link headers.

Step 2: Delete View Resources

Step 3: Delete Source Resource

After all View Resources are deleted, the source can be deleted successfully:

Response:

Idempotency

View Definition Idempotency

View Definitions are idempotent by name and content:

Scenario 1: Identical Name and Content

First request response:

Repeat request with identical content:

The same Definition URI is returned. No duplicate is created.

Scenario 2: Same Name, Different Content

Response:

View Binding Idempotency

View Bindings are idempotent by destination, definition, and source:

First request:

Repeat request:

The same Binding is returned. No duplicate is created.

Data Matching

VIEW_CONTAINER Filtering Behavior

When a VIEW_CONTAINER binding is created, not all Source Resources necessarily produce View Resources. The View Definition's GraphQL query acts as a filter.

Resources That Produce Views:

  • JSON resources where the query produces non-empty results

Resources That Don't Produce Views:

  • Non-JSON resources (text files, images, etc.)

  • JSON resources where the query produces empty results (no matching data)

  • Resources with malformed JSON

  • Resources with data that doesn't match the schema

Example: Selective View Creation

Source Container:

View Definition:

Result in View Container:

Non-JSON Source Resources

Behavior with Non-JSON Resources

When a View Binding references a non-JSON Source Resource:

VIEW_RESOURCE:

  • Binding creation succeeds (201 Created)

  • View resource is NOT created

  • Accessing the View Resource URI returns 404 Not Found

VIEW_CONTAINER:

  • Binding creation succeeds (201 Created)

  • Non-JSON resources are silently skipped

  • Only JSON resources that match the query produce View Resources

Example: Text File Source

Response:

Accessing the view:

Response:

The binding exists but no View Resource is materialized because the source is not JSON.

Authorization

Authentication

All Data Views API requests require authentication using either DPoP (Demonstrating Proof-of-Possession) or Bearer tokens.

For details on authentication methods, see Authentication in Solid.

View Registry Authorization

Read Operations (GET)

Any authenticated user can list and retrieve View Definitions:

Response:

Write Operations (POST, DELETE)

Creating and deleting View Definitions requires special registry authorization. Only WebIDs in the registry authorization allow-list can perform these operations.

Authorized Request:

Response:

Unauthorized Request:

Response:

Configuration

Registry authorization is configured via environment variables or application properties. Only ESS Administrators are allowed to edit the allow-list. See Registry Authorization Configuration for details.

View Binding Authorization

Creating Bindings

To create a View Binding, you must have data subject permission for the storage containing the Source Resource. This means you must be the owner of the Pod where the Source Resource resides.

Authorized Request (own Storage):

Response:

Unauthorized Request (not data subject):

Response:

Accessing View Resources

View Resources are regular Solid resources and respect standard access control:

  • ACP Policies: Apply ACP policies to View Resources to control access

  • Access Grants: Issue Access Grants for View Resources

  • Read Permission: Users need read permission to access View Resources

View Resources do NOT inherit access control from Source Resources. You must explicitly grant access to View Resources.

Error Responses

The Data Views API uses RFC 7807 Problem Detailsarrow-up-right format for error responses.

View Definition Errors

Invalid GraphQL Schema

Response:

Query-Schema Mismatch

Response:

View Definition Name Conflict

Response:

Exceeds Security Limits

Response:

View Binding Errors

Missing Required Fields

Response:

Source and Destination on Different Storages

Response:

Invalid Binding Type

Response:

VIEW_CONTAINER URI Requirements

Response:

Non-Existent View Definition

Response:

Source Resource Not Found

Response:

Authorization Errors

Insufficient Registry Authorization

Response:

Insufficient Data Subject Permission

When the source and destination are on the same storage but the agent making the request is not the data subject:

Response:

Configuration

The Data Views Service is configured via environment variables or application properties files. Only ESS Administrators can adjust these settings.

Security Limits

These settings control GraphQL query complexity to prevent resource exhaustion attacks.

Maximum Query Depth

Limits the maximum nesting depth of GraphQL queries.

Default: 10

Example: A query with depth 12 would be rejected:

Maximum Query Complexity

Limits the total complexity score of GraphQL queries. Complexity is calculated based on field count and nesting.

Default: 1000

Queries with complexity scores exceeding this limit are rejected with a 400 Bad Request error.

Maximum List Size

Limits the maximum number of items that can be processed in array filtering operations.

Default: 10000

If a Source Resource contains an array with more than this many items, the query is rejected.

GraphQL Schema Caching

View Definitions' GraphQL schemas are parsed and cached to improve performance. These settings control cache behavior.

Cache Maximum Size

Maximum number of parsed schemas to keep in cache.

Default: 100

When the cache reaches this size, least-recently-used schemas are evicted.

Cache Expiry Time

How long parsed schemas remain in cache after last access.

Default: 1h (1 hour)

Valid values: Time duration string (e.g., 30m, 2h, 1d)

After this time, schemas are evicted and must be re-parsed on next use.

Registry Authorization

Controls which WebIDs are authorized to create and delete view definitions in the registry. Only WebIDs in the allow-list can perform write operations (POST, DELETE) on /views/registry. Read operations (GET) are available to all authenticated users.

Allow List Configuration

Specify authorized WebIDs using a comma-separated list:

Default: Empty (no users authorized for write operations)

Format: Comma-separated list of WebID URIs

Example with multiple WebIDs:

circle-exclamation

Additional Information

Best Practices

Security

  • Minimize View Definitions: Create View Definitions that expose only necessary fields, following the principle of least privilege

  • Review GraphQL queries: Ensure queries don't inadvertently expose sensitive data through complex filtering logic

  • Use short-lived Access Grants: When sharing View Resources, use Access Grants with appropriate expiration times

  • Monitor audit logs: Regularly review audit events for view operations to detect unauthorized access attempts

Performance

  • Reuse View Definitions: Create generic View Definitions that can be applied to multiple resources instead of creating specific definitions for each resource

  • Limit query complexity: Keep GraphQL queries simple to reduce processing overhead

  • Use VIEW_CONTAINER sparingly: VIEW_CONTAINER bindings process all resources in a container, which can be resource-intensive for large containers

Data Management

  • Document View Definitions: Include clear descriptions and purposes for View Definitions to help future maintenance

  • Plan destination URIs: Use consistent naming conventions for View Resources to make them easy to discover and manage

  • Clean up unused bindings: Regularly delete View Bindings that are no longer needed to free resources and simplify management

Development Workflow

  • Use preview before binding: Always preview VIEW_RESOURCE bindings before creating them to verify the output matches expectations

  • Test with sample data: Create View Definitions using sample data that includes edge cases (null values, empty arrays, malformed dates)

  • Implement retry logic: Always use retry logic when accessing View Resources to account for asynchronous processing

Further Reading

Last updated