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.
File Location
Section titled “File Location”Page-Level API Files
Section titled “Page-Level API Files”src/pages/{routeName}/_graphql/api.tsPage-level API files are located in the _graphql directory (underscore prefix hides from Astro routing).
Examples:
src/pages/articles/_graphql/api.tssrc/pages/places/_graphql/api.tssrc/pages/homepage/_graphql/api.tsComponent-Level API Files
Section titled “Component-Level API Files”src/components/{feature}/graphql/api.tssrc/pages/{route}/_components/{feature}/api.tsComponent-level API files are in the graphql subdirectory or directly alongside the component.
Examples:
src/components/relatedArticles/graphql/api.tssrc/components/newsletterForm/graphql/api.tssrc/pages/articles/_components/saveControls/api.tsFunction Naming
Section titled “Function Naming”Page-Level Functions
Section titled “Page-Level Functions”Use {routeName}PageAPI pattern:
export async function articlesPageAPI(variables: Variables) {}
// src/pages/articles/[slug]/_graphql/api.tsexport async function articlePageAPI({ slug, previewEnabled }: Props) {}Component-Level Functions
Section titled “Component-Level Functions”Use {componentName}API pattern:
export async function relatedArticlesAPI(slug: string) {}
// src/pages/articles/_components/saveControls/api.tsexport async function saveButtonAPI(props: Props) {}Typical Structure
Section titled “Typical Structure”// Importsimport { 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; }}Common Patterns
Section titled “Common Patterns”Multiple GraphQL Services
Section titled “Multiple GraphQL Services”// Contentful (default)const { data } = await graphqlApi({ query: CMS_QUERY, variables,});
// Rakiura GraphQLconst { data } = await graphqlApi({ api: "mapi", query: API_QUERY, variables,});
// Shopifyconst { data } = await graphqlApi({ api: "shopify", query: SHOP_QUERY, variables,});Authenticated Requests
Section titled “Authenticated Requests”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);}Related Files
Section titled “Related Files”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 definitionsRelated
Section titled “Related”- Function Naming - Function naming conventions
- File Organization - Directory structure patterns
- transform.ts - Data transformation functions
- page.query.graphql - GraphQL query files
- GraphQL Query Patterns - API patterns and best practices