Skip to content

api.ts

The api.ts file contains GraphQL API functions for fetching and mutating data. It serves as the integration layer between GraphQL operations and application components.

src/pages/{routeName}/_graphql/api.ts

Page-level API files are located in the _graphql directory (underscore prefix hides from Astro routing).

Examples:

src/pages/articles/_graphql/api.ts
src/pages/places/_graphql/api.ts
src/pages/homepage/_graphql/api.ts
src/components/{feature}/graphql/api.ts
src/pages/{route}/_components/{feature}/api.ts

Component-level API files are in the graphql subdirectory or directly alongside the component.

Examples:

src/components/relatedArticles/graphql/api.ts
src/components/newsletterForm/graphql/api.ts
src/pages/articles/_components/saveControls/api.ts

Use {routeName}PageAPI pattern:

src/pages/articles/_graphql/api.ts
export async function articlesPageAPI(variables: Variables) {}
// src/pages/articles/[slug]/_graphql/api.ts
export async function articlePageAPI({ slug, previewEnabled }: Props) {}

Use {componentName}API pattern:

src/components/relatedArticles/graphql/api.ts
export async function relatedArticlesAPI(slug: string) {}
// src/pages/articles/_components/saveControls/api.ts
export async function saveButtonAPI(props: Props) {}
// Imports
import { graphqlApi } from "#graphql/graphqlClient";
import QUERY from "./page.query.graphql";
import { transformData } from "./transform";
import type {
QueryType,
QueryVariables,
} from "#graphql/generated/contentful/schema";
// API function(s)
export async function featurePageAPI(params: Params) {
// graphqlApi handles GraphQL/network errors internally
const { data } = await graphqlApi<QueryType, QueryVariables>({
query: QUERY,
variables: { ...params },
});
// Validate minimum required data
if (!data?.requiredField) {
console.error("Missing required data", {
component: "featurePageAPI",
context: params,
});
return null;
}
// Catch transformation errors
try {
return transformData(data);
} catch (error) {
console.error("Transformation error", {
error: error.message,
component: "featurePageAPI",
context: params,
});
return null;
}
}
// Contentful (default)
const { data } = await graphqlApi({
query: CMS_QUERY,
variables,
});
// Rakiura GraphQL
const { data } = await graphqlApi({
api: "mapi",
query: API_QUERY,
variables,
});
// Shopify
const { data } = await graphqlApi({
api: "shopify",
query: SHOP_QUERY,
variables,
});
export async function saveButtonAPI({ accessToken, esid }: Props) {
const { data } = await graphqlApi({
api: "mapi",
query: GET_USER_SAVE,
variables: { sourceId: esid, sourceType: "ARTICLE" },
requestHeaders: {
Authorization: `Bearer ${accessToken}`,
},
});
return Boolean(data.save);
}

API files work alongside other GraphQL files:

_graphql/
├── page.query.graphql # GraphQL query
├── api.ts # API functions (this file)
├── transform.ts # Data transformations
└── transform.types.ts # Transform type definitions