GraphQL Extensibility API
The GraphQL Extensibility API allows developers to extend existing GraphQL operations used by a Drop-in to meet additional data requirements without increasing code complexity or negatively impacting performance. This API provides a flexible and efficient way to customize GraphQL Fragments by integrating build-time modifications into the storefrontâs development pipeline.
Extend your Drop-in GraphQL Fragments
Section titled âExtend your Drop-in GraphQL FragmentsâTo enable GraphQL Fragments to be extensible in your Drop-in, follow these steps:
Define Your Fragments
Section titled âDefine Your FragmentsâCreate the content for the fragments you are exporting.
// ./src/api/fragments/MyFragment.ts
export const MY_FRAGMENT = ` fragment MY_FRAGMENT on FragmentInterface { firstname lastname
favorites { uid name } }`;Create Fragments Manifest File
Section titled âCreate Fragments Manifest FileâNext, create a new file for your project to list all the fragments you want to expose.
// ./src/api/fragments.ts
export { MY_FRAGMENT } from '@/my-dropin/api/graphql/MyFragment';Update the API Configuration
Section titled âUpdate the API ConfigurationâFinally, add the new file reference to the API configuration in ./.elsie.js.
// ./.elsie.js
module.exports = { name: 'MyDropin', api: { root: './src/api', importAliasRoot: '@/my-dropin/api', fragments: './fragments.ts', // đ add this line }, components: [ { id: 'Components', root: './src/components', importAliasRoot: '@/my-dropin/components', cssPrefix: 'my-dropin', default: true, }, ], containers: { root: './src/containers', importAliasRoot: '@/my-dropin/containers', }, schema: { endpoint: process.env.ENDPOINT, headers: {} }};Extend the Data module
Section titled âExtend the Data moduleâNow that we have made our fragments extensible, we must extend the data model used in our Drop-ins.
Define Typing to the Initializer API
Section titled âDefine Typing to the Initializer APIâFirst, add the typing to your initializer API in ./src/api/initialize/initialize.ts.
// ./src/api/initialize/initialize.ts
import { Initializer, Model } from '@adobe-commerce/elsie/lib';import { Lang } from '@adobe-commerce/elsie/i18n';import { MyModel } from '@/my-dropin/data/models';
type ConfigProps = { langDefinitions?: Lang;
// đ add your models configuration models?: { MyModel?: Model<MyModel>; },};
export const initialize = new Initializer<ConfigProps>({ init: async (config) => { const defaultConfig = {}; initialize.config.setConfig({ ...defaultConfig, ...config }); },
listeners: () => [],});
export const config = initialize.config;Extend the Data Transformer
Section titled âExtend the Data TransformerâThen, use the configuration to extend the data transformer the model uses by deep merging the existing data transformation with the new configuration.
// ./src/data/transforms/transform-my-model.tsimport { merge } from '@adobe-commerce/elsie/lib';import { MyModel } from '@/my-dropin/data/models';
export function transformMyModel(data: any): MyModel { const model = { name: `${data.firstname} ${data.lastname}`, favorites: data.favorites, };
// Merge custom transformer, if provided return merge( model, // default transformer config.getConfig().models?.MyModel?.transformer?.(data) // custom transformer );}Using the GraphQL Extensibility Feature in Your Storefront
Section titled âUsing the GraphQL Extensibility Feature in Your StorefrontâBy extending the GraphQL Fragments and Models of drop-ins, you can leverage the drop-inâs existing GraphQL operations and add extra fields needed to meet your specific business requirements. This approach enhances the user experience while maintaining code simplicity and performance efficiency since all modifications are integrated into the storefrontâs development build-time pipeline.
Extend Drop-inâs Fragments and Models
Section titled âExtend Drop-inâs Fragments and ModelsâFollow these steps to extend the GraphQL Fragment and Model in your Drop-in:
Extend the GraphQL Fragment
Section titled âExtend the GraphQL FragmentâUse the overrideGQLOperations function to extend the existing GraphQL Fragment, allowing you to add fields to the fragment as needed.
The overrideGQLOperations functions accept an array of configuration objects where you must specify:
npm: string
Section titled ânpm: stringâThe node module name of the drop-in. i.e. â@dropins/my-dropinâ.
operations: string[]
Section titled âoperations: string[]âAn array of string or template literal with operations.
- Only one definition can be provided in the operation.
- These must match the operation name as provided by the drop-in. i.e.
MY_FRAGMENT. - The operations must be valid GraphQL operations, such as Fragment. i.e.
fragment MY_FRAGMENT on FragmentInterface { ... }. - In the case of a Fragment, the fragment name must match the same interface as the drop-in. i.e.
FragmentInterface. - If an existing field that has variables is used:
- If not variables are provided, the existing variables will be used. i.e.
favorites(page: 1) { ... }. - If new variables are provided, the new variable will be added. i.e.
favorites(page: 1, offset: 5) { ... }. - If the existing variables are changed, the new variables will be used. i.e.
favorites(page: 2) { ... }.
- If not variables are provided, the existing variables will be used. i.e.
import overrideGQLOperations from '@dropins/build-tools/gql-extend.js';
overrideGQLOperations([ { npm: '@dropins/my-dropin', operations: [` fragment MY_FRAGMENT on FragmentInterface { age
favorites { quantity } } `], },]);Extend the Data Model
Section titled âExtend the Data ModelâNext, update the data models to include the new fields added to the fragment, ensuring that the additional data is correctly processed and available for use in the drop-in. i.e., Slots, Event Bus, etc.
import * as api from '@dropins/storefront-cart/api.js';
initializers.register(api.initialize, { models: { MyModel: { transformer: (data) => ({ age: data?.age, favorites: data.favorites.map((favorite) => ({ quantity: favorite.quantity, })), }), }, },});