Developing a data source extension

A data source extension makes data available to your Frontastic site which:

  1. Can be configured and influenced from Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`.
  2. Is available immediately when the site loads (also during Server Side Rendering)
  3. Can be connected simultaneously to multiple Frontastic componentsFrontastic components - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code. on the same page

1. Specify a data source type

A data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. needs to be specified so the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. knows that it exists and can expose configuration to its users. So, a data source schema (see the Frontastic schemas article for more information) is created. The schemaschema - The framework behind a Frontastic component and the fields that are available within the Frontastic studio. defines the data source type identifier (which is used to resolve the data source to your extension code) and a list of fields for configuration. For example:

{
    "customDataSourceType": "example/star-wars-movie",
    "name": "Star wars movie",
    "category": "Content",
    "icon": "stars",
    "schema": [
        {
            "name": "Settings",
            "fields": [
                {
                    "label": "Movie ID",
                    "field": "movieId",
                    "type": "string",
                    "translatable": false
                }
            ]
        }
    ]
}

The customDataSourceType field is required and needs to comply with the format <vendor>/<identifier>. You'll usually use your company name or project name as the <vendor> and use a speaking identifier for the data source.

The name specifies how the data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. is referenced in the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. and should be understandable for Frontastic studio users. category and icon are the specific schema fields for visualization in the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`..

The schema part holds a list of configuration sections where each section consists of some fields. This area is typical for Frontastic schema definitions. More details are in the Frontastic schemas article.

This example exposes a single input field where a Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. user can enter the ID of a Star Wars movie episode. The data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. will then fetch information about the selected movie from a backend API.

2. Announce the data source type to the Frontastic studio

To let the Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. know about your new data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site., you need to upload the schema you just created. To do that:

  1. Open the Frontastic studio and click Developer on the dashboard
  1. Click Custom data sources
  1. Click the blue add icon and select your schema (or drag the schema file into the browser)

3. Configure a data source on a page folder

A data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. is always connected to a page folderpage folder - A way of structuring the pages within a project and forms the URL structure – they can contain sub-folders. Known as `node` in code.. With that, the data delivered by it is made available to the currently active page in it and so to all components that exist on this page.

  1. Go to the Site builder
  1. Select a page folder and click the settings icon
  1. Expand the Data source section and click + Add data source filter
  1. Select your new data source from the dropdown

This opens the data source filter editor.

  1. Enter the Movie ID for the episode number (ZmlsbXM6MQ==), change the filter name if you want to, and then click Save
  1. Check your data source filter is there, then click Save

4. Create a component that consumes the data source

Frontastic won't load data from a data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. unless there's at least 1 Frontastic componentFrontastic component - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code. assigned to the live page version which consumes it. So, such a component must be specified and placed on a page version.

A simple test component like the below works:

{
    "tasticType": "example/star-wars-opening-crawl",
    "name": "Star Wars opening crawl",
    "icon": "movie_filter",
    "category": "general",
    "schema": [
        {
            "name": "Data source",
            "fields": [
                {
                    "label": "Star Wars movie",
                    "field": "movieData",
                    "type": "stream",
                    "streamType": "example/star-wars-movie"
                }
            ]
        }
    ]
}

This component has only 1 configuration field of type stream of which the streamType references the previously specified data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site.. This means: When this component is used, it needs a corresponding data source on the page folder and needs to be attached to it.

📘

stream is the old name for dataSource. We're working on an improvement to support the correct names in the future.

5. Place the component onto a page

  1. Click Components on the left-hand navigation
  1. Click the blue add icon and select the Frontastic component schema (or drag the schema into the browser window)
  1. Click Site builder on the left-hand navigation
  1. Select the page folder you added the data source to earlier and click New, then select Create page version
  1. Click the blue add icon in the middle section
  1. Select the 1 layout element
  1. Find your Frontastic component in the section on the left and drag it into the layout element
  1. Select the data source filter you created earlier in the page folder settings
  1. Click Save
  1. Click the more icon on your draft page version and select Make default

6. Test the data source

Now that a page folderpage folder - A way of structuring the pages within a project and forms the URL structure – they can contain sub-folders. Known as `node` in code. exists with a configured instance of the data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. and a page versionpage version - A page can have multiple versions and in different states within a page folder, such as draft, scheduled, live, and so on. that has a Frontastic componentFrontastic component - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code. to consume it, the data sourcedata source - The data provided from an API to display products, content, or anything from an integration or extension. A data source filter is created and can be selected for a Frontastic component that will display the data source filter on your commerce site. can be tested. This works best using your favorite HTTP client, like Postman, HTTPie, or curl.

To access the Frontastic API hubAPI hub - The API hub combines our code, your code, and APIs to create the backend of a commerce site. Any backend development or extensions are done here. Known as `Catwalk` in code. on your Frontastic sandboxFrontastic sandbox - A virtual machine hosted in the cloud that you can use for backend and some frontend development. They're provisioned from the developer area of the Frontastic studio., look up its project URL in Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`.. To do this, open the Frontastic studio, click Developer, then Sandboxes, find your sandbox, and then click the copy icon next to Host.

Then you can fire a GET request to the path /frontastic/page on your sandbox URL. The request needs to be sent with the correct Accept header for application/json and the following 2 query parameters:

  • path holds the URL path to the Frontastic page folder you created (for example, /developer/lea or from above /datasource)
  • locale holds a valid locale for your project (for example, en_US).

For example:

curl -X 'GET' -H 'Accept: application/json' 'https://<projectname>-<sandbox-host>/frontastic/page?path=/developer/lea&locale=en_US'

This call will return a full Frontastic page payload of which only the following parts are significant for the data source test:

{
        ...
    "data": {
        "_type": "Frontastic\\Catwalk\\NextJsBundle\\Domain\\PageViewData",
        "dataSources": {
            "ee92bc20-f4b5-4e9d-98cf-b8c8d7300563": {
                "message": "No stream handler for stream type example/star-wars-movie configured.",
            }
        }
    },
    "page": {
        ...
    },
    "pageFolder": {
        "_type": "Frontastic\\Catwalk\\NextJsBundle\\Domain\\Api\\PageFolder",
                ...
        "dataSourceConfigurations": [
            {


                "configuration": {
                    "movieId": "ZmlsbXM6MQ=="
                },


                "name": "Star wars movie",
                "streamId": "ee92bc20-f4b5-4e9d-98cf-b8c8d7300563",
                "type": "example/star-wars-movie"
            }
        ],
          ...
    }
}

The data key of the payload contains the page folder global data, which comes from data sources. In this example, there's only 1 data source that contains an error message (because it wasn't implemented yet). page is out of scope here. The pageFolder, among other information, contains the dataSourceConfigurations where the configuration of the desired Star Wars episode can be found.

This part is especially noteworthy because the data source implementation will receive this payload as in the configuration.

7. Implementing the data source code

You need to register the data source in the extension configuration to implement the data source code. This is usually the index.ts file in packages/<project>/backend.

import { DataSourceConfiguration, DataSourceContext, DataSourceResult } from '@frontastic/extension-types';

export default {
  'data-sources': {
    'example/star-wars-movie': (config: DataSourceConfiguration, context: DataSourceContext): DataSourceResult => {
      return {
        dataSourcePayload: 'We should fetch episode ' + (config.configuration.episode || 'UNKNOWN'),
      } as DataSourceResult
    }
  }
};

A data source function is defined by its 2 parameters:

  • The configuration config (of type DataSourceConfiguration) and its context (of type DataSourceContext)
  • The return value of type DataSourceResult

As can be seen from the example, the config contains the configuration values from Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. as specified earlier by the data source schema.

📘

The Frontastic studioFrontastic studio - The interface you use to manage, build, and edit all areas of your project and commerce sites. Previously known as `backstage`. allows users to store configuration even if mandatory parameters are missing. So, you should always code defensive when using configuration values.

Repeating the test HTTP call will now reveal a data source result:

{
  "data": {
    "_type": "Frontastic\\Catwalk\\NextJsBundle\\Domain\\PageViewData",
    "dataSources": {
      "ee92bc20-f4b5-4e9d-98cf-b8c8d7300563": {
        "dataSourcePayload": "We should fetch episode 4"
      }
    }
  },
  ...
}

While the above example illustrates the types used with a data source, you wouldn't want to only return the data source configuration. So, here's an actual implementation towards an API.

📘

We're using the Axios library to perform HTTP requests here. To reproduce this example, you need to add this as a dependency, for example, using yarn add axios. You can use any HTTP library that works with Node.js, the native Node.js HTTP package, or an SDK library of an API provider.

import { DataSourceConfiguration, DataSourceContext, DataSourceResult } from '@frontastic/extension-types';
import axios from 'axios';
export default {
  'data-sources': {
    'example/star-wars-movie': async (config: DataSourceConfiguration, context: DataSourceContext): Promise<DataSourceResult> => {
      return await axios.post<DataSourceResult>(
        'https://swapi-graphql.netlify.app/.netlify/functions/index',
        {
          query: '{film(id:"' + config.configuration.movieId + '") {title, episodeID, openingCrawl, releaseDate}}',
        }
      ).then((response):  DataSourceResult => {
        return {
          dataSourcePayload: response.data,
        } as DataSourceResult
      }).catch((reason) => {
        return {
          dataSourcePayload: {
            ok: false,
            error: reason.toString(),
          }
        } as DataSourceResult
      });
    }
  }
};

This fetches the corresponding movie from the Star Wars API GraphQL example implementation and returns the corresponding payload as the result of the data source. Repeating the testing HTTP call will show it as part of the Frontastic page payload:

{
  "data": {
    "_type": "Frontastic\\Catwalk\\NextJsBundle\\Domain\\PageViewData",
    "dataSources": {
      "ac8a8700-6a84-4c02-9160-4fc2fced3fe9": {
        "dataSourcePayload": {
          "data": {
            "film": {
              "title": "A New Hope",
              "episodeID": 4,
              "openingCrawl": "It is a period of civil war.\r\nRebel spaceships, striking\r\nfrom a hidden base, have won\r\ntheir first victory against\r\nthe evil Galactic Empire.\r\n\r\nDuring the battle, Rebel\r\nspies managed to steal secret\r\nplans to the Empire's\r\nultimate weapon, the DEATH\r\nSTAR, an armored space\r\nstation with enough power\r\nto destroy an entire planet.\r\n\r\nPursued by the Empire's\r\nsinister agents, Princess\r\nLeia races home aboard her\r\nstarship, custodian of the\r\nstolen plans that can save her\r\npeople and restore\r\nfreedom to the galaxy....",
              "releaseDate": "1977-05-25"
            }
          }
        }
      }
    }
  }
  ...
}

8. Consume the data source

A Frontastic componentFrontastic component - A customizable building block that's used together with other components to create a commerce site. Known as `tastic` for short in code. implementation can now consume this data, for example, following the previously shown Frontastic component schema. With this, Frontastic will automatically make the data source payload available through the data property:

const StarWarsOpeningCrawl = ({ data }) => {
  return (<marquee direction='up' style={{ whiteSpace: 'pre-wrap' }}>
    {data.movieData.dataSource.openingCrawl}
  </marquee>);
};

Further reading


Did this page help you?