afv-library/skills/fetching-webapp-rest-api/SKILL.md
k-j-kim 9ba064174a
feat: syncing webapp skills sync to afv @W-21338965@ (#57)
* feat: removing old webapp skills

* feat: adding sync of skills from webapps to afv

* feat: adding the first iteration of skills

* feat: pin template deps to latest npm versions and flatten skill folders

- Add pin-template-deps.js to resolve "*" deps to exact npm versions
- Integrate pinning into sync-template-skills npm script
- Remove check-template-skills-versions.js (no longer needed)
- Simplify workflow to single sync step
- Flatten skill output: one folder per skill with cleaned names

Made-with: Cursor

* fix: resolve skill validation errors

- Move .template-versions.json from skills/ to root
- Shorten skill names to meet 64-char limit:
  - salesforce-webapp-feature-micro-frontend-generating-micro-frontend-lwc → salesforce-webapp-micro-frontend-lwc
  - salesforce-webapp-feature-react-agentforce-conversation-client-integrating-agentforce-conversation-client → salesforce-webapp-agentforce-conversation-client
  - salesforce-webapp-feature-react-file-upload-implementing-file-upload → salesforce-webapp-react-file-upload
- Expand descriptions to meet 20-word minimum with trigger context

* Add webapp skills from template, sync script updates

- Rename skill folders from salesforce-webapp-* to *-webapp-* convention
- Update sync-template-skills.js: set SKILL.md front matter name to dest folder
- Remove sync-template-skills workflow and pin-template-deps script
- Add .synced-template-skills.json manifest, deploying-webapp-to-salesforce skill
- Replace salesforce-webapp-designing-webapp-ui-ux with designing-webapp-ui-ux

Made-with: Cursor

* Align SKILL.md front matter name with folder for all webapp skills

Made-with: Cursor

* Fix skill validation: description length and trigger context for configuring-webapp-metadata, creating-webapp

Made-with: Cursor

* Rename sync script to sync-webapp-skills, drop manifest file

- Rename sync-template-skills.js to sync-webapp-skills.js
- Update package.json script to sync-webapp-skills
- Remove .synced-template-skills.json creation and add to .gitignore

Made-with: Cursor

* Revert sync-react-b2e-sample and sync-react-b2x-sample to upstream version

Made-with: Cursor

* Sync script: pin b2e and b2x to latest, sync skills from template

- Pin both template packages to latest in sync-webapp-skills.js
- Update package.json / package-lock.json (b2x 1.109.0)
- Sync skills: managing-webapp-agentforce-conversation-client, bar-line-chart,
  remove building-webapp-analytics-charts and integrating-webapp-agentforce-conversation-client
- Minor skill content updates

Made-with: Cursor

* Remove interactive map, weather widget, and Unsplash skills (no longer in template)

Made-with: Cursor

---------

Co-authored-by: Hemant Singh Bisht <hsinghbisht@salesforce.com>
2026-03-19 22:46:27 +05:30

5.1 KiB

name description paths
fetching-webapp-rest-api REST API usage via the Data SDK fetch method. Use when implementing Chatter, Connect REST, Apex REST, UI API REST, or Einstein LLM calls — only when GraphQL is not sufficient.
**/*.ts
**/*.tsx
**/*.graphql

Salesforce REST API via Data SDK Fetch

Use sdk.fetch from the Data SDK when GraphQL is not sufficient. The SDK applies authentication, CSRF handling, and base URL resolution. Always use optional chaining (sdk.fetch?.()) and handle the case where fetch is not available.

Invoke this skill when you need to call Chatter, Connect REST, Apex REST, UI API REST, or Einstein LLM endpoints.

API Version

Use the project's API version. It is typically injected as __SF_API_VERSION__; fallback to "65.0":

declare const __SF_API_VERSION__: string;
const API_VERSION = typeof __SF_API_VERSION__ !== "undefined" ? __SF_API_VERSION__ : "65.0";

Base Path

URLs are relative to the Salesforce API base. The SDK prepends the correct base path. Use paths starting with /services/....


Chatter API

User and collaboration data. No GraphQL equivalent.

Endpoint Method Purpose
/services/data/v{version}/chatter/users/me GET Current user (id, name, email, username)
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 };

Connect REST API

File and content operations.

Endpoint Method Purpose
/services/data/v{version}/connect/file/upload/config GET Upload config (token, uploadUrl) for file uploads
const sdk = await createDataSDK();
const configRes = await sdk.fetch?.(`/services/data/v${API_VERSION}/connect/file/upload/config`, {
  method: "GET",
});

if (!configRes?.ok) throw new Error(`Failed to get upload config: ${configRes?.status}`);
const config = await configRes.json();
const { token, uploadUrl } = config;

Apex REST

Custom Apex REST resources. Requires corresponding Apex classes in the org. CSRF protection is applied automatically for services/apexrest URLs.

Endpoint Method Purpose
/services/apexrest/auth/login POST User login
/services/apexrest/auth/register POST User registration
/services/apexrest/auth/forgot-password POST Request password reset
/services/apexrest/auth/reset-password POST Reset password with token
/services/apexrest/auth/change-password POST Change password (authenticated)
/services/apexrest/{resource} GET/POST Custom Apex REST resources

Example (login):

const sdk = await createDataSDK();
const response = await sdk.fetch?.("/services/apexrest/auth/login", {
  method: "POST",
  body: JSON.stringify({ email, password, startUrl: "/" }),
  headers: { "Content-Type": "application/json", Accept: "application/json" },
});

Apex REST paths do not include the API version.


UI API (REST)

When GraphQL cannot cover the use case. Prefer GraphQL when possible.

Endpoint Method Purpose
/services/data/v{version}/ui-api/records/{recordId} GET Fetch a single record
const sdk = await createDataSDK();
const response = await sdk.fetch?.(`/services/data/v${API_VERSION}/ui-api/records/${recordId}`);

Einstein LLM Gateway

AI features. Requires Einstein API setup.

Endpoint Method Purpose
/services/data/v{version}/einstein/llm/prompt/generations POST Generate text from Einstein LLM
const sdk = await createDataSDK();
const response = await sdk.fetch?.(`/services/data/v${API_VERSION}/einstein/llm/prompt/generations`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    additionalConfig: { applicationName: "PromptTemplateGenerationsInvocable" },
    promptTextorId: prompt,
  }),
});

if (!response?.ok) throw new Error(`Einstein LLM failed (${response?.status})`);
const data = await response.json();
return data?.generations?.[0]?.text ?? "";

General Pattern

import { createDataSDK } from "@salesforce/sdk-data";

const sdk = await createDataSDK();

if (!sdk.fetch) {
  throw new Error("Data SDK fetch is not available in this context");
}

const response = await sdk.fetch(url, {
  method: "GET", // or POST, PUT, PATCH, DELETE
  headers: { "Content-Type": "application/json", Accept: "application/json" },
  body: method !== "GET" ? JSON.stringify(payload) : undefined,
});

if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();

Reference

  • Parent: accessing-data — enforces Data SDK usage for all Salesforce data fetches
  • GraphQL: using-graphql — use for record queries and mutations when possible
  • createRecord from @salesforce/webapp-experimental/api for UI API record creation (uses SDK internally)