πŸ”’ Guided

Pre-launch preview. Authorised access only.

Incorrect code

Guided by A Guide to Cloud
Explore AB-900 AI-901
Guided DP-800 Domain 2
Domain 2 β€” Module 8 of 11 73%
18 of 28 overall

DP-800 Study Guide

Domain 1: Design and Develop Database Solutions

  • Table Design: Columns, Types, and Indexes Free
  • Constraints: Protecting Your Data Free
  • Specialised Tables and Graph Queries Free
  • JSON in SQL: Store, Query, and Index
  • Programmability: Views, Functions, Procedures, and Triggers
  • Advanced T-SQL: CTEs, Windows, and Correlated Queries
  • Pattern Power: Regular Expressions in T-SQL
  • Fuzzy String Matching: Finding Similar Text
  • AI-Assisted SQL with GitHub Copilot Free
  • MCP: Connecting AI to Your Database

Domain 2: Secure, Optimize, and Deploy Database Solutions

  • Encryption: Always Encrypted and Column-Level
  • Dynamic Data Masking and Row-Level Security
  • Permissions, Auditing, and Passwordless Access
  • Transaction Isolation and Concurrency
  • Query Performance: Plans, DMVs, and Query Store
  • SQL Database Projects: Build and Validate
  • CI/CD Pipelines for SQL Databases
  • Data API Builder: REST and GraphQL from SQL
  • Securing AI and API Endpoints
  • Change Detection: CES, CDC, and Change Tracking
  • Azure Integration and Monitoring

Domain 3: Implement AI Capabilities in Database Solutions

  • External AI Models: Choose, Create, Manage
  • Embeddings: Design, Chunk, and Generate
  • Choose Your Search Strategy
  • Vector Data: Types, Indexes, and Storage
  • Vector Search: Distance, ANN, and ENN
  • Hybrid Search and Reciprocal Rank Fusion
  • RAG with SQL: Prompt, Process, Respond

DP-800 Study Guide

Domain 1: Design and Develop Database Solutions

  • Table Design: Columns, Types, and Indexes Free
  • Constraints: Protecting Your Data Free
  • Specialised Tables and Graph Queries Free
  • JSON in SQL: Store, Query, and Index
  • Programmability: Views, Functions, Procedures, and Triggers
  • Advanced T-SQL: CTEs, Windows, and Correlated Queries
  • Pattern Power: Regular Expressions in T-SQL
  • Fuzzy String Matching: Finding Similar Text
  • AI-Assisted SQL with GitHub Copilot Free
  • MCP: Connecting AI to Your Database

Domain 2: Secure, Optimize, and Deploy Database Solutions

  • Encryption: Always Encrypted and Column-Level
  • Dynamic Data Masking and Row-Level Security
  • Permissions, Auditing, and Passwordless Access
  • Transaction Isolation and Concurrency
  • Query Performance: Plans, DMVs, and Query Store
  • SQL Database Projects: Build and Validate
  • CI/CD Pipelines for SQL Databases
  • Data API Builder: REST and GraphQL from SQL
  • Securing AI and API Endpoints
  • Change Detection: CES, CDC, and Change Tracking
  • Azure Integration and Monitoring

Domain 3: Implement AI Capabilities in Database Solutions

  • External AI Models: Choose, Create, Manage
  • Embeddings: Design, Chunk, and Generate
  • Choose Your Search Strategy
  • Vector Data: Types, Indexes, and Storage
  • Vector Search: Distance, ANN, and ENN
  • Hybrid Search and Reciprocal Rank Fusion
  • RAG with SQL: Prompt, Process, Respond
Domain 2: Secure, Optimize, and Deploy Database Solutions Premium ⏱ ~15 min read

Data API Builder: REST and GraphQL from SQL

Turn your SQL database into REST and GraphQL endpoints with Data API Builder β€” configure entities, pagination, caching, stored procedures, and deploy to Azure.

APIs without writing API code

β˜• Simple explanation

Think of a restaurant menu.

You have a kitchen full of ingredients (your database). Customers want specific dishes (data). Normally, you hire a chef (backend developer) to take orders, cook, and serve. That is expensive and slow.

Data API Builder (DAB) is like an automated kitchen. You write a menu (configuration file) that says β€œthe Customers table is available as an endpoint.” DAB handles the cooking β€” it translates HTTP requests into SQL queries, serves the results as JSON, and handles pagination, filtering, and caching. No chef required.

You get both REST (simple, URL-based) and GraphQL (flexible, query-based) endpoints from the same config.

Data API Builder (DAB) is an open-source engine that generates REST and GraphQL endpoints from a JSON configuration file. It connects to Azure SQL, SQL Server, PostgreSQL, MySQL, or Cosmos DB and translates API requests into parameterised queries. DAB handles authentication (via EasyAuth, JWT, or custom providers), role-based authorization at the entity and field level, pagination, filtering, sorting, and response caching. It runs as a container, a Static Web Apps database connection, or a standalone process.

The DAB configuration file

Everything in DAB is driven by a single JSON configuration file. Here is the structure Leo Torres at SearchWave uses:

// dab-config.json (simplified structure)
// data-source: where the database lives
// runtime: REST and GraphQL global settings
// entities: each table/view/procedure exposed as an API

Initialising a config

# Install DAB CLI
dotnet tool install -g Microsoft.DataApiBuilder

# Initialise a new config for Azure SQL
dab init \
  --database-type "mssql" \
  --connection-string "@env('SQL_CONNECTION_STRING')" \
  --host-mode "Development"

This creates dab-config.json with the database connection and default settings.

Adding entities

# Expose the Products table as REST and GraphQL
dab add Product \
  --source "dbo.Products" \
  --permissions "anonymous:read" \
  --rest true \
  --graphql true

# Expose a stored procedure
dab add SearchProducts \
  --source "dbo.usp_SearchProducts" \
  --source.type "stored-procedure" \
  --source.params "searchTerm:string" \
  --permissions "authenticated:execute" \
  --rest.methods "get" \
  --graphql.operation "query"

The resulting entity configuration in JSON:

"Product": {
  "source": {
    "object": "dbo.Products",
    "type": "table"
  },
  "rest": {
    "enabled": true,
    "path": "/products"
  },
  "graphql": {
    "enabled": true,
    "type": {
      "singular": "Product",
      "plural": "Products"
    }
  },
  "permissions": [
    {
      "role": "anonymous",
      "actions": [
        {
          "action": "read"
        }
      ]
    },
    {
      "role": "authenticated",
      "actions": [
        {
          "action": "*",
          "fields": {
            "include": ["*"],
            "exclude": ["InternalCost"]
          }
        }
      ]
    }
  ]
}

REST vs GraphQL in DAB

REST vs GraphQL endpoints in Data API Builder
FeatureRESTGraphQL
URL pattern/api/products/42/graphql (single endpoint, query in body)
Field selectionReturns all fields (or use $select OData)Client specifies exact fields needed
Related dataSeparate requests per entityNested queries fetch related entities in one call
MutationsPOST, PUT, PATCH, DELETE verbsmutation keyword in query body
Stored proceduresMapped to specific HTTP methodsMapped as query or mutation operations
CachingHTTP cache headers (standard)DAB-specific caching per entity
Best forSimple CRUD, broad tooling supportComplex queries, mobile apps (minimise data transfer)

REST examples

GET  /api/products              β†’ List all products (paginated)
GET  /api/products/42           β†’ Get product with ID 42
POST /api/products              β†’ Create a new product (body = JSON)
PUT  /api/products/42           β†’ Replace product 42
PATCH /api/products/42          β†’ Update specific fields
DELETE /api/products/42         β†’ Delete product 42

# Filtering (OData syntax)
GET /api/products?$filter=price gt 100 and category eq 'Electronics'

# Sorting
GET /api/products?$orderby=price desc

# Pagination
GET /api/products?$first=10&$after=eyJpZCI6MTB9

GraphQL examples

# Query with field selection
query {
  products(filter: { price: { gt: 100 } }) {
    items {
      id
      name
      price
    }
  }
}

# Query with nested relationship
query {
  products {
    items {
      name
      category {
        name
      }
      reviews {
        items {
          rating
          comment
        }
      }
    }
  }
}

# Mutation (create)
mutation {
  createProduct(item: {
    name: "Wireless Headphones"
    price: 79.99
    categoryId: 3
  }) {
    id
    name
  }
}

Pagination, filtering, and caching

Pagination

DAB uses cursor-based pagination by default (not page numbers). Each response includes nextLink (REST) or hasNextPage with endCursor (GraphQL).

// REST response with pagination
{
  "value": [ ... ],
  "nextLink": "/api/products?$after=eyJpZCI6MjV9"
}

Why cursor-based? It is stable when data changes. Page-number pagination breaks if rows are inserted between page requests (you might skip or duplicate items).

Caching

Enable caching to reduce database load for read-heavy endpoints:

"Product": {
  "source": { "object": "dbo.Products", "type": "table" },
  "cache": {
    "enabled": true,
    "ttl-seconds": 300
  }
}

Caching works for read operations only (GET/query). Mutations always hit the database. You can set TTL (time-to-live) per entity β€” long TTL for rarely-changing reference data, short TTL for frequently-updated records.

πŸ’‘ Exam tip: When NOT to cache

Do not enable caching for entities where users expect real-time data: financial transactions, inventory counts, or order statuses. Stale cached data in these scenarios causes business errors. The exam may describe a scenario where a team enables caching and users see outdated stock levels β€” the answer is to disable caching for that entity or reduce the TTL.

Exposing stored procedures and views

Stored procedures

Stored procedures map to specific REST methods and GraphQL operation types:

"SearchProducts": {
  "source": {
    "object": "dbo.usp_SearchProducts",
    "type": "stored-procedure",
    "parameters": {
      "searchTerm": "string",
      "maxResults": "int"
    }
  },
  "rest": {
    "path": "/search-products",
    "methods": ["get"]
  },
  "graphql": {
    "operation": "query",
    "type": {
      "singular": "SearchResult",
      "plural": "SearchResults"
    }
  }
}

Calling the procedure:

REST: GET /api/search-products?searchTerm=wireless&maxResults=10
GraphQL: query { searchProducts(searchTerm: "wireless", maxResults: 10) { ... } }

Views

Views are configured identically to tables but are read-only by default. DAB recognises that views may not support INSERT/UPDATE:

"ActiveProducts": {
  "source": {
    "object": "dbo.vw_ActiveProducts",
    "type": "view",
    "key-fields": ["id"]
  }
}

The key-fields property is required for views because DAB cannot infer the primary key from the view definition.

GraphQL relationships

DAB can create GraphQL relationships between entities, allowing nested queries:

"Product": {
  "source": { "object": "dbo.Products", "type": "table" },
  "relationships": {
    "category": {
      "cardinality": "one",
      "target.entity": "Category",
      "source.fields": ["categoryId"],
      "target.fields": ["id"]
    },
    "reviews": {
      "cardinality": "many",
      "target.entity": "Review",
      "source.fields": ["id"],
      "target.fields": ["productId"]
    }
  }
}

With these relationships, a single GraphQL query can fetch a product, its category, and all its reviews in one request. REST requires three separate calls.

πŸ’‘ Scenario: Leo builds the SearchWave product API

Leo Torres at SearchWave needs to expose their product catalog, categories, and reviews as APIs for a new mobile app. Instead of building a .NET API from scratch (weeks of work), Leo configures DAB:

  1. Three entities: Product, Category, Review
  2. GraphQL relationships so the mobile app can fetch a product with category and reviews in one call
  3. Caching on Category (changes rarely) and Product (5-minute TTL), no caching on Review (users expect immediate visibility)
  4. A stored procedure for full-text search, exposed as a GraphQL query
  5. Anonymous users can read products; authenticated users can create reviews

The entire API is running in under an hour. No backend code written.

Deployment options

OptionHow It WorksBest For
Azure Static Web AppsBuilt-in database connection feature β€” DAB runs alongside your frontendJAMstack apps, SPAs with database backends
Azure Container AppsRun DAB as a container with auto-scalingProduction APIs needing scale and isolation
Azure App ServiceDeploy as a container to App ServiceTeams already using App Service
Local / self-hostedRun dab start directly on any machineDevelopment and testing

Container deployment

FROM mcr.microsoft.com/dotnet/aspnet:8.0
COPY dab-config.json /App/dab-config.json
ENV DATABASE_CONNECTION_STRING="Server=..."
ENTRYPOINT ["dab", "start", "--config", "/App/dab-config.json"]
Question

What is the difference between REST and GraphQL in DAB?

Click or press Enter to reveal answer

Answer

REST uses URL patterns with HTTP verbs (GET /api/products/42) and returns all fields. GraphQL uses a single endpoint (/graphql) where the client specifies exactly which fields and related entities to return. REST is simpler; GraphQL is more flexible for complex data needs.

Click to flip back

Question

Why does DAB use cursor-based pagination instead of page numbers?

Click or press Enter to reveal answer

Answer

Cursor-based pagination uses an opaque token (cursor) pointing to the last item returned. This is stable even when data changes between requests. Page-number pagination can skip or duplicate rows if items are inserted or deleted between page fetches.

Click to flip back

Question

Why must you specify key-fields when exposing a view in DAB?

Click or press Enter to reveal answer

Answer

DAB needs a primary key to support single-item lookups (GET /api/entity/id) and to generate correct GraphQL types. Tables have primary keys defined in their schema, but views do not. You must explicitly tell DAB which field or fields uniquely identify each row.

Click to flip back

Knowledge Check

Leo at SearchWave configures a DAB entity for the Reviews table. Users report that new reviews they submit do not appear immediately when they refresh the product page. Reviews appear after a few minutes. What is the most likely cause?

Knowledge Check

A team wants to expose a stored procedure that calculates monthly revenue. The procedure accepts a month parameter and returns aggregated sales data. How should this be configured in DAB?

🎬 Video coming soon

Next up: Securing AI and API Endpoints β€” lock down your REST, GraphQL, and AI model endpoints with authentication, authorization, and managed identity.

← Previous

CI/CD Pipelines for SQL Databases

Next β†’

Securing AI and API Endpoints

Guided

I learn, I simplify, I share.

A Guide to Cloud YouTube Feedback

© 2026 Sutheesh. All rights reserved.

Guided is an independent study resource and is not affiliated with, endorsed by, or officially connected to Microsoft. Microsoft, Azure, and related trademarks are property of Microsoft Corporation. Always verify information against Microsoft Learn.