Frontastic supports GraphQL to query backend systems so that you can integrate any GraphQL based API with Frontastic. We don't limit usage or datasets in any way. This is so you can integrate any concept you want to and merge the data from your APIs with the data from the commerce or content APIs.

Using configurations you can allow users to adapt or even write GraphQL queries 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`.. We'll go through some examples for this in this article.

Frontastic doesn't allow you to query its data partially from the frontend using GraphQL. The main reason for this is, that users 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`. define what data should be shown on a certain page. The Frontastic <glossary:API hub>> then ensures that the correct data is fetched accordingly to the configuration. The main interface between developer and business user is the 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. and our minimal frontend framework provides your components automatically with all the data needed, as configured 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`..

This means: If there's a certain frontend component on a page and it's currently visible, depending on the device, then Frontastic will fetch the data from the GraphQL backend automatically. And this can depend on context, like the current user, query parameters in the URL, and, the configuration from 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`..

1. Create a Frontastic component

To be able to visualize the data coming out of the GraphQL 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., we need to create 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..

For this example, we'll be using the Frontastic CLIFrontastic CLI - Our Commandline Interface (CLI) that you can use for frontend development., our name for the component will be streamExample, and the custom data source will be example/graphql.

  1. Run frontastic generate tastic in the Frontastic CLIFrontastic CLI - Our Commandline Interface (CLI) that you can use for frontend development. and enter the name of your new 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.
frontastic generate tastic
? Please enter a name for the new Tastic streamExample
  1. Edit the schema file to have a section like the below which includes the streamType (you can also add any other configuration options, but we'll focus on the custom 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. here)
{
    "tasticType": "show/streamExample",
    "name": "Stream Example",
    "icon": "source",
    "category": "general",
    "schema": [
        {
            "name": "The Basics",
            "fields": [
                {
                    "label": "Data Source",
                    "field": "dataSource",
                    "type": "stream",
                    "streamType": "example/graphql"
                }
            ]
        }
    ]
}
  1. Add the schema to 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`. (see the Frontastic components article for more information)

  2. Update the JSX file to display the raw data from the custom data source (we'll view the query results in this example)

import React from 'react'
import PropTypes from 'prop-types'
    
function StreamExampleTastic ({ data }) {
    return <pre>{JSON.stringify(data.dataSource || 'No data yet', null, 2)}</pre>
}
    
StreamExampleTastic.propTypes = { data: PropTypes.object.isRequired }
    
export default StreamExampleTastic

Now we have the 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. updated, we need to create a custom stream handler.

2. Create a custom data source handler

To be able to use the data from our custom data source, we need to create a custom data source handler (also known as the tasticFieldHandler).

  1. Create a new bundle using the below command (we're using Test for this example)
bin/console frontastic:create:bundle -v Test

See the creating a backend bundle article for more information on bundles.

  1. Open the services.xml file in the new bundle folder (for example, <customer>/<project>/src/php/TestBundle/Resources/config/services.xml)

  2. Uncomment the section in the created services.xml and register the custom 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. using the tasticFieldHandler (see our TasticFieldHandler article for more information)

<service id="Show\TestBundle\Domain\GraphQLStreamHandler">
    <tag name="frontend.tasticFieldHandler"/>
</service>

We're using a tag for now but we'll add additional service parameters later.

  1. Create a PHP class

🚧

The string returned by getType must match the name of the custom 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. in the tastic.json we created in step 2 of the 1st section.

namespace Show\TestBundle\Domain;

use Frontastic\Catwalk\FrontendBundle\Domain\TasticFieldHandlerV3;
use Frontastic\Catwalk\ApiCoreBundle\Domain\Context;
use Frontastic\Catwalk\FrontendBundle\Domain\Node;
use Frontastic\Catwalk\FrontendBundle\Domain\Page;
use Frontastic\Catwalk\FrontendBundle\Domain\Tastic;

class GraphQLStreamHandler extends TasticFieldHandlerV3
{
    public function getType(): string
    {
        return 'example/graphql';
    }

    public function handle(Context $context, Node $node, Page $page, Tastic $tastic, $fieldValue)
    {
        return 'data';
    }
}

The handle method can return anything, which will then be passed to the 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.. You need to make sure that the returned data is handled in the 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. or you could map or filter the data in the custom data source handler.

  1. Query a GraphQL endpoint

In our example, we'll use the Frontastic HTTP client using the service name Frontastic\Common\HttpClient and have the services.xml inject it into our custom . We'll be querying the public Star Wars API GraphQL endpoint available under https://graphql.org/swapi-graphql.

public function handle(Context $context, Node $node, Page $page, Tastic $tastic, $fieldValue)
    {
        return json_decode($this->httpClient->request(
            'POST',
            'https://swapi-graphql.netlify.app/.netlify/functions/index',
            json_encode(['query' => '{ allFilms { films { title } } }']),
            ['Accept: application/json', 'Content-Type: application/json'],
        )->body);
    }

You can also use file_get_contents or plain curl to query the endpoint and you can modify the query if you want to. In the next section, we'll show you how to set up the ability to modify the query 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`..

3. Custom data source configuration

Now we have our 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. and our custom data source handler, we can make it so the query is configurable 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`. (see this section of the TasticFieldHandler article for more information).

To do this, we need to create a schema for 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. type which defines the configuration options in the page builderpage builder - An interface you work with to build your pages. and make sure this configuration can be handled.

  1. Create a schema file similar to below

🚧

The customStreamType property must match the streamType defined in the schema.json from step 2 in the 1st section.

{
    "customStreamType": "example/graphql",
    "name": "GraphQL",
    "category": "Content",
    "icon": "source",
    "schema": [
        {
            "name": "Configuration",
            "fields": [
                {
                    "label": "Query",
                    "field": "query",
                    "type": "text",
                    "default": "",
                    "translatable": false
                }
            ]
        }
    ]
}

In this example, the full GraphQL query will be configurable.

  1. Update the handle method in the PHP class for your bundle so that the $fieldValue variable matches the field in the schema
public function handle(Context $context, Node $node, Page $page, Tastic $tastic, $fieldValue)
    {
        return json_decode($this->httpClient->request(
            'POST',
            'https://swapi-graphql.netlify.app/.netlify/functions/index',
            json_encode(['query' => ($fieldValue['query'] ?? '{ allFilms { films { title } } }')]),
            ['Accept: application/json', 'Content-Type: application/json'],
        )->body);
    }

Now, the GraphQL query can be specified in the page builderpage builder - An interface you work with to build your pages. of 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`.. You could even make it so it can specify the URL and maybe access credentials and you would have a generic GraphQL 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 works when just displaying raw data, but in a real project, your 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. will expect a certain data structure and so won't work with random queries. You'll probably only want to make certain parameters in the query configurable, let's look at how to do that.

commercetools and GraphQL

If you're using commercetools as your product API, we can use the already authorized commercetools client to request data using the commercetools GraphQL API (see the commercetools GraphQL API documentation for more information).

📘

The following example will only work in projects where the product API uses commercetools.

  1. Define the stream handler in the services.xml in your newly created bundle
<service id="CommercetoolsClient" class="Frontastic\Common\ProductApiBundle\Domain\ProductApi\Commercetools\Client">
            <factory service="frontastic.catwalk.product_api"
                method="getDangerousInnerClient"
            />
        </service>

        <service id="Show\TestBundle\Domain\CommercetoolsStreamHandler">
            <argument type="service" id="CommercetoolsClient" />

            <tag name="frontend.tasticFieldHandler"/>
        </service>

This will pass our already authenticated commercetools client to the custom data source handler we created earlier.

  1. Use the request method of the commercetools client to run a GraphQL query against the space in commercetools which has been configured for your project
public function handle(Context $context, Node $node, Page $page, Tastic $tastic, $fieldValue)
    {
        return $this->commercetools->request(
            'POST', '/graphql', [], [],
            json_encode([
                'query' => 'query ($sku: String!) { product(sku: $sku) { id, version } }',
                'variables' => [
                    'sku' => $fieldValue['sku'] ?? 'M0E20000000ED0W',
                ]
            ]),
        )->wait();
    }

In this example, we use the $fieldValue['sku'] which references a sku configuration field from the custom data source schema. This means that the SKU of the product can be configured 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`..

Since we query the id and version of products, the output of the 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. will just contain the following. So, you can fetch exactly the data you need using this mechanism.

{
  "data": {
    "product": {
      "id": "8d2f35a1-0386-4ca4-9dfc-9501999386c5",
      "version": 1348
    }
  }
}

Query parameters

We can also combine the configuration from 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`. with request parameters if we want to. In the following example, we'll check if the SKU is defined as a query parameter (/myPage?sku=S0MESKU). If this parameter exists we'll read the SKU from the query parameter. If not, we fall back to the value configured by the business user. If that configuration is also empty we just return null. The logic might be different for your case, but this allows for loading different data based on user interaction, too.

public function handle(Context $context, Node $node, Page $page, Tastic $tastic, $fieldValue)
    {
        $sku = $_GET['sku'] ?? $fieldValue['sku'] ?? null;
        if (!$sku) {
            return null;
        }

        return $this->commercetools->request(
            'POST', '/graphql', [], [],
            json_encode([
                'query' => 'query ($sku: String!) { product(sku: $sku) { id, version } }',
                'variables' => ['sku' => $sku],
            ]),
        )->wait();
    }

GraphCMS and GraphQL

If you're using commercetools as your product API, we can use the already authorized GraphCMS client to request data using the GraphCMS GraphQL API (see the GraphCMS GraphQL API documentation.

📘

The following example will only work in projects where the product API uses GraphCMS.

  1. Define the stream handler in the services.xml in your newly created bundle
<service id="GraphcmsClient" class="Frontastic\Common\ContentApiBundle\Domain\ContentApi\GraphCMS\Client">
            <factory service="frontastic.catwalk.content_api"
                method="getDangerousInnerClient"
            />
        </service>

        <service id="Show\TestBundle\Domain\GraphcmsStreamHandler">
            <argument type="service" id="GraphcmsClient" />

            <tag name="frontend.tasticFieldHandler"/>
        </service>

This will pass our already authenticated GraphCMS client to the custom data source handler we created earlier.

  1. Use the query method of the GraphCMS client to run any GraphQL query against GraphCMS
public function handle(Context $context, Node $node, Page $page, Tastic $tastic, $fieldValue)
    {
        return json_decode($this->graphcms->query(
            '{ products (where: { price_gt: 45 }) { id, name, price } }'
        )->wait());
    }

You'll see the implementation of our custom data source handler looks even simpler in this case. Our example space contains products with the schema name Product so we can query for all products with a price higher than 45. The sensible queries highly depend on your content schema and values like the 45 should be made configurable by business users – see the earlier examples for a more detailed description of how to do this.

This query will then give exactly the content elements you requested with only the properties you need in the frontend:

{
  "data": {
    "products": [
      {
        "id": "ckdu44mn40gxh010405uwgbtw",
        "name": "Unisex Long Sleeve Tee",
        "price": 100
      },
      {
        "id": "ckdu48unc0gzq0158mbzvyzg3",
        "name": "Snapback",
        "price": 100
      },
      /* … */
    ]
  }
}

Did this page help you?