
Accessing Webapp Data
- 1 installs
- 787 repo stars
- Updated August 5, 2026
- forcedotcom/afv-library
Enforces Salesforce data-access patterns requiring all record fetches from web apps to go through the Data SDK with GraphQL preferred.
About
Provides rules for fetching Salesforce data from web apps, mandating the @salesforce/sdk-data Data SDK with GraphQL as the preferred query method. A developer uses it when adding or modifying code that reads Salesforce records, Chatter, or Connect API data.
- All Salesforce fetches must use createDataSDK(), never direct fetch or axios
- Requires optional chaining on sdk.graphql/sdk.fetch for surfaces where they may be undefined
Accessing Webapp Data by the numbers
- 1 all-time installs (skills.sh)
- Ranked #3,830 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/forcedotcom/afv-library --skill accessing-webapp-dataAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 787 |
| Last updated | August 5, 2026 |
| Repository | forcedotcom/afv-library ↗ |
What it does
Enforces Salesforce data-access patterns requiring all record fetches from web apps to go through the Data SDK with GraphQL preferred.
Files
Salesforce Data Access
Guidance for accessing Salesforce data from web apps. All Salesforce data fetches MUST use the Data SDK (@salesforce/sdk-data). The SDK provides authentication, CSRF handling, and correct base URL resolution — direct fetch or axios calls bypass these and are not allowed.
Mandatory: Use the Data SDK
Every Salesforce data fetch must go through the Data SDK. Obtain it viacreateDataSDK(), then usesdk.graphql?.()orsdk.fetch?.(). Never callfetch()oraxiosdirectly for Salesforce endpoints.
Optional Chaining and Graceful Handling
Always use optional chaining when calling sdk.graphql or sdk.fetch — these methods may be undefined in some surfaces (e.g., Salesforce ACC, MCP Apps). Handle the case where they are not available gracefully:
const sdk = await createDataSDK();
// ✅ Use optional chaining
const response = await sdk.graphql?.(query);
// ✅ Check before using fetch
if (!sdk.fetch) {
throw new Error("Data SDK fetch is not available in this context");
}
const res = await sdk.fetch(url);For GraphQL, if sdk.graphql is undefined, the call returns undefined — handle that in your logic (e.g., throw a clear error or return a fallback). For sdk.fetch, check availability before calling when the operation is required.
Preference: GraphQL First
GraphQL is the preferred method for querying and mutating Salesforce records. Use it when:
- Querying records (Account, Contact, Opportunity, custom objects)
- Creating, updating, or deleting records (when GraphQL supports the operation)
- Fetching related data, filters, sorting, pagination
Use `sdk.fetch` only when GraphQL is not sufficient. For REST API usage, invoke the fetching-rest-api skill, which documents:
- Chatter API (e.g.,
/services/data/v65.0/chatter/users/me) - Connect REST API (e.g.,
/services/data/v65.0/connect/file/upload/config) - Apex REST (e.g.,
/services/apexrest/auth/login) - UI API REST (e.g.,
/services/data/v65.0/ui-api/records/{recordId}) - Einstein LLM Gateway
---
Getting the SDK
import { createDataSDK } from "@salesforce/sdk-data";
const sdk = await createDataSDK();---
Example 1: GraphQL (Preferred)
For record queries and mutations, use GraphQL via the Data SDK. Invoke the using-graphql skill for the full workflow (schema exploration, query authoring, codegen, lint validate).
import { createDataSDK, gql } from "@salesforce/sdk-data";
import type { GetAccountsQuery } from "../graphql-operations-types";
const GET_ACCOUNTS = gql`
query GetAccounts {
uiapi {
query {
Account(first: 10) {
edges {
node {
Id
Name { value }
}
}
}
}
}
}
`;
export async function getAccounts() {
const sdk = await createDataSDK();
const response = await sdk.graphql?.<GetAccountsQuery>(GET_ACCOUNTS);
if (response?.errors?.length) {
throw new Error(response.errors.map((e) => e.message).join("; "));
}
return response?.data?.uiapi?.query?.Account?.edges?.map((e) => e?.node) ?? [];
}---
Example 2: Fetch (When GraphQL Is Not Sufficient)
For REST endpoints that have no GraphQL equivalent, use sdk.fetch. Invoke the `fetching-rest-api` skill for full documentation of Chatter, Connect REST, Apex REST, UI API REST, and Einstein LLM endpoints.
import { createDataSDK } from "@salesforce/sdk-data";
declare const __SF_API_VERSION__: string;
const API_VERSION = typeof __SF_API_VERSION__ !== "undefined" ? __SF_API_VERSION__ : "65.0";
export async function getCurrentUser() {
const sdk = await createDataSDK();
const response = await sdk.fetch?.(`/services/data/v${API_VERSION}/chatter/users/me`);
if (!response?.ok) throw new Error(`HTTP ${response?.status}`);
const data = await response.json();
return { id: data.id, name: data.name };
}---
Anti-Patterns (Forbidden)
Direct fetch to Salesforce
// ❌ FORBIDDEN — bypasses Data SDK auth and CSRF
const res = await fetch("/services/data/v65.0/chatter/users/me");Direct axios to Salesforce
// ❌ FORBIDDEN — bypasses Data SDK
const res = await axios.get("/services/data/v65.0/chatter/users/me");Correct approach
// ✅ CORRECT — use Data SDK
const sdk = await createDataSDK();
const res = await sdk.fetch?.("/services/data/v65.0/chatter/users/me");---
Clarifying Vague Data Requests
When a user asks about data and the request is vague, clarify before implementing. Ask which of the following they want:
- Application code — Add or modify code in a specific web app so the app performs the data interaction at runtime (e.g., GraphQL query in the React app)
- Local SF CLI — Run Salesforce CLI commands locally (e.g.,
sf data query,sf data import tree) to interact with the org from the terminal - Local example data — Update or add local fixture/example data files (e.g., JSON in
data/) for development or testing - Other — Data export, report generation, setup script, etc.
Do not assume. A request like "fetch accounts" could mean: (1) add a GraphQL query to the app, (2) run sf data query in the terminal, or (3) update sample data files. Confirm the intent before proceeding.
---
Decision Flow
1. Need to query or mutate Salesforce records? → Use GraphQL via the Data SDK. Invoke the using-graphql skill. 2. Need Chatter, Connect REST, Apex REST, UI API REST, or Einstein LLM? → Use sdk.fetch. Invoke the fetching-rest-api skill. 3. Never use fetch, axios, or similar directly for Salesforce API calls.
---
Reference
- GraphQL workflow: invoke the
using-graphqlskill (.a4drules/skills/using-graphql/) - REST API via fetch: invoke the
fetching-rest-apiskill (.a4drules/skills/fetching-rest-api/) - Data SDK package:
@salesforce/sdk-data(createDataSDK,gql,NodeOfConnection) createRecordfor UI API record creation:@salesforce/webapp-experimental/api(uses Data SDK internally)