Edit

Share via


Field selection (Projection) in REST

Projection helps you return only what your client actually needs. Smaller payloads improve performance, reduce network costs, and reduce client-side parsing overhead. Data API builder (DAB) implements projection for REST through the $select query parameter.

Note

REST query parameter names (including $select) are case sensitive. Field names are also case sensitive based on what you configured or exposed.

Go to the GraphQL version of this document.

Basic selection

Pattern

GET /api/{entity}?$select=FieldA,FieldB,FieldC

If $select is omitted, DAB returns all fields the caller’s role is authorized to read (subject to include and exclude configuration and field-level permissions). There's no wildcard token like *; omitting $select is how you request the full allowed shape.

Examples

# Return all accessible fields
GET /api/author

# Return only first_name
GET /api/author?$select=first_name

# Return only first_name and last_name
GET /api/author?$select=first_name,last_name

Internal vs response columns

You aren't required to project primary key or ordering fields. If omitted, they don't appear in the JSON response. However, DAB may internally fetch extra columns needed to enforce security policies (row-level filters, field masks) and handle pagination cursors ($after / nextLink).

Note

These internally fetched columns are removed before the response unless you explicitly request them.

Example

GET /api/book?$select=id,title&$orderby=publisher_id desc&$first=5

Conceptual SQL

SELECT TOP (6) -- first (5) + 1 probe row for paging
  [b].[id],
  [b].[sku_title] AS title
FROM dbo.books AS [b]
ORDER BY [b].[publisher_id] DESC, [b].[id] ASC;

Response

{
  "value": [
    { "id": 101, "title": "Example 1" },
    { "id": 77,  "title": "Example 2" },
    { "id": 42,  "title": "Example 3" },
    { "id": 33,  "title": "Example 4" },
    { "id": 5,   "title": "Example 5" }
  ],
  "nextLink": "..."
}

Learn more about pagination and the after keyword.

The extra internal columns and the sixth probe row aren't visible in the payload.

Stored procedures

For stored procedure–backed entities, $select isn't interpreted as a projection clause. Instead, query string key/value pairs (except recognized system parameters like $filter, $orderby, etc.) are treated as stored procedure parameters. $select has no effect; the procedure’s result set defines the shape.

Example configuration

{
  "runtime": {
    "pagination": {
      "default-page-size": 100,
      "max-page-size": 100000
    }
  },
  "entities": {
    "Book": {
      "source": {
        "type": "table",
        "object": "dbo.books"
      },
      "mappings": {
        "sku_title": "title",
        "sku_price": "price"
      },
      "relationships": {
        "book_category": {
          "cardinality": "one",
          "target.entity": "Category",
          "source.fields": [ "category_id" ],
          "target.fields": [ "id" ]
        }
      }
    },
    "Category": {
      "source": {
        "type": "table",
        "object": "dbo.categories"
      },
      "relationships": {
        "category_books": {
          "cardinality": "many",
          "target.entity": "Book",
          "source.fields": [ "id" ],
          "target.fields": [ "category_id" ]
        }
      }
    }
  }
}

See also

Concept REST GraphQL Purpose
Projection $select items Choose which fields to return
Filtering $filter filter Restrict rows by condition
Sorting $orderby orderBy Define the sort order
Page size $first first Limit the number of items per page
Continuation $after after Continue from the last page using a cursor

Note

REST keywords begin with $, following OData conventions.