1. Introduction

Content as a Service provides the editorial data of FirstSpirit via a uniform JSON-based data format that can be consumed by any endpoint. The data is updated transparently in the CaaS platform when it is changed or released in the FirstSpirit editorial system. With a cloud installation of the CaaS platform the data can be efficiently accessed worldwide. In FirstSpirit, only the form configurations and the data maintained by the editorial system are accessed. Templating in FirstSpirit is completely eliminated and is shifted to the front end or front end services (see Crownpeak PWA Template for a reference implementation of a Progressive Web App).

The FirstSpirit developer can thus concentrate completely on modeling the domain-oriented objects and creating the corresponding input components. The following section describes the conventions for data format and URLs, as well as the optimal delivery of content for different consumers.

In the remainder of this document the abbreviation CaaS will be used instead of Content as a Service.

2. Introduction FirstSpirit module

The CaaS Connect module is the link between FirstSpirit editorial environment and the CaaS platform that acts as the content delivery. This connection is largely invisible to the editorial team and only requires attention in the event of a technical problem. The editors can always view the current state of data directly via the CaaS platform. As soon as a change has been made in FirstSpirit, the synchronization is triggered in the background, and the database immediately reflects the change.

There are traditional and fragment projects in FirstSpirit. Technical pages - and thus also the elements that are transferred to the CaaS platform - correspond to the page references in traditional projects and to the fragments in fragment projects. For the sake of simplicity we speak of pages in both cases. The CaaS Connect module automatically distinguishes between traditional and fragment projects.

2.1. CaaS URLs

The module creates documents in the CaaS platform for the following FirstSpirit elements:

  • Page references

  • Media

  • Global content pages

  • Project settings page

  • Datasets

Each element will be represented as multiple documents. For each activated language of the FirstSpirit project and for both the preview and release state, a document is created. Each of these documents can be identified and referenced with a unique URL.

Languages are considered active when the option Generate language is enabled in the project language configuration.

2.1.1. URL schema

The CaaS URL for a document consists of four parts: tenant id, project identifier, collection identifier, and document identifier. The tenant id is the maintained name or abbreviation of the tenant. It is set in the CaaS Connect Service by the server administrator. The project identifier is the GID of the FirstSpirit project. The collection identifier allows you to differentiate between release and preview state. It contains either the value release.content or preview.content. The document identifier is composed of the FirstSpirit GID of the FirstSpirit element and the language. Together with the base URL of the CaaS endpoint, this results in the fully qualified URL of a document.

CaaS URLs for project settings do not use their FirstSpirit GID as document identifier but instead use the identifier projectsettings.

Example:

The tenant id is defaultTenant.

The FirstSpirit project GID is e54cb80e-1f9c-4e8d-84b8-022f473202eb.

The fully qualified CaaS URL of a sample page with the GID f6910b22-6ae8-4ce1-af45-c7b364b3117a in preview and for the English language looks like this

The collections created by CaaS Connect only contain documents with a standard format (see chapter Data format). Other features of the CaaS Connect module or users of the CaaS platform API expect documents with this format when querying these collections. It is recommended to not create your own documents in these collections to avoid breaking functionality of other features of the CaaS Connect module or cause issues for API users.

The configuration dialog of the project component shows an overview of all collection URLs of the project.

2.2. Data format

Unlike traditional FirstSpirit projects and earlier module versions, CaaS Connect version 3 or later does not support either output channels or FirstSpirit templating. Instead, a JSON document is generated for each page of the project, based on the toJson standard of FirstSpirit. An adaptation of the format is not possible. This restriction allows to deliver a complete, standardized data format via CaaS platform, so that all consuming endpoints can work with the same data format. Since the standard data format is very comprehensive, the platform offers filtering and aggregation capabilities to reduce data volumes for mobile end points, for example. For more information about CaaS platform, see platform documentation.

Since the CaaS URLs derive the document identifier from a unique FirstSpirit ID (among other things), it is necessary to use a filter when querying a document using its name. To query a CaaS page (a FirstSpirit page reference) with the name services a GET request is executed with the following URL:

For more information on queries for the CaaS platform, see platform documentation.

2.2.1. CaaS JSON format

The standard JSON format of FirstSpirit serves as the basis for the CaaS JSON format and is extended by the CaaS Connect module both with CaaS specific JSON format configuration, as well as with some attributes that simplify its usage. The CaaS specific format configurations include reducing the output of datasets to references, the indirect referencing of records of a content projection, and enabling the output of the FirstSpirit metadata.

Dataset URLs:
FirstSpirit does not address individual datasets and instead works with content projections or selects and embeds datasets in pages. In CaaS projects, individual datasets are identified by a unique URL and can be queried with it. Therefore, pages do not embed datasets, but contain references to the stored datasets in the CaaS platform.

JSON snippet example
{
   "fsType" : "FS_DATASET",
   "name" : "st_button_link",
   "value" : {
      "fsType" : "DatasetReference",
      "target" : {
         "entityType" : "product",
         "fsType" : "Dataset",
         "identifier" : "fae0687b-c365-4851-919e-566f4d587201",
         "schema" : "products"
      }
   }
}

The route attribute has been replaced by the new routes array, but is still calculated for compatibility reasons.

Dataset Routes:
The routes attribute is an array that lists all available content projections of a dataset as individual objects. A dataset has multiple routes if it is part of multiple content projections and therefore multiple preview pages are available for that dataset.

The pageRef attribute is the FirstSpirit-GID of the associated page reference.

JSON snippet example
{
  "routes": [
          {
            "pageRef": "39332e1e-0a42-4fb9-934a-dd3efe58cbc8",
            "route": "/Company/Press/Solar-systems-unveiled-at-Old-Trafford-stadium.html"
          },
          {
            "pageRef": "78dc7762-657b-4524-ab00-debbfd5e6d62",
            "route": "/Company/Solarnews/Solar-systems-unveiled-at-Old-Trafford-stadium.html"
          }
  ]
}

New dataset routes are always created by the UrlFactory for the preview state. Already existing stored custom URLs will be considered in preview state.

PageRef Routes:
The route attribute contains the URL of a pageRef rendered with the configured project-specific URL factory.

JSON snippet example
{
  "fsType": "PageRef",
  "name": "news_overview",
  "route": "/Company/Press/Press-Overview.html"
}

Fragment metadata:
The attribute fragmentMetaData contains the attributes id (fragment ID) and type (fragment type).

JSON snippet example
{
    "fragmentMetaData": {
        "id": "378d5ec9_58f1_4dec_83bc_724dc93de5c2",
        "type": "news"
    }
}

Locale:
The locale attribute contains the attributes identifier (abbreviation of the language), country (associated country) and language (associated language).

JSON snippet example
{
    "locale": {
        "identifier": "EN",
        "country": "GB",
        "language": "en"
    }
}

Media references:
References to media point to the associated document of the medium. The URLs to the actual binary data of the medium are inside the referenced document.

JSON snippet example of a media reference
{
   "st_header_image": {
        "fsType": "FS_REFERENCE",
        "name": "st_header_image",
        "value": {
            "fsType": "Media",
            "name": "header_home",
            "identifier": "b7fd2e2c-a022-44d6-ae2d-f0b9fd48f9a2",
            "uid": "header_home",
            "uidType": "MEDIASTORE_LEAF",
            "mediaType": "PICTURE",
            "url": "https://some-caas-api/some-tenant/631e4786-0dc3-4db6-bad8-adaad685944a.preview.content/b7fd2e2c-a022-44d6-ae2d-f0b9fd48f9a2.de_DE"
        }
    }
}

Content2Section:
The JSON data of content projections or its sections contain references to its records when using the standard JSON configuration of FirstSpirit. However, the CaaS Connect module uses a specific configuration for the JSON format so that the records are not referenced directly, but indirectly via a query object. For this purpose, the query object contains identifiable attributes of the content projection.

JSON snippet example
{
   "displayName" : "blog",
   "entityType" : "blog",
   "filterParams" : {},
   "fsType" : "Content2Section",
   "maxPageCount" : 0,
   "name" : "blog",
   "ordering" : [
      {
         "ascending" : false,
         "attribute" : "fs_id"
      }
   ],
   "query" : null,
   "recordCountPerPage" : 1,
   "schema" : "global",
   "template" : {
      "displayName" : "Blog entry",
      "fsType" : "TableTemplate",
      "identifier" : "e657e0f0-0fd3-456f-b5ab-560a879ca748",
      "name" : "Blog entry",
      "uid" : "global.blog",
      "uidType" : "TEMPLATESTORE_SCHEMA"
   }
}

Project master language:
The project settings document has the attribute projectConfiguration with the sub-attribute masterLocale in which the project master language is contained.

JSON snippet example
{
  ..,
  "projectConfiguration": {
    "masterLocale": "en_GB"
  }
}

Changing the project master language does not automatically update the document in the CaaS platform. To update the document, the project schedules Total Sync for performing data synchronization can be used (see chapter Total Sync).

2.3. Preview and release state

An essential distinction between release and preview data states is made by both FirstSpirit and the CaaS Connect module. The platform manages both states of data, which are distinguishable by different CaaS URLs (see URL schema). A synchronization of both data states is always based on certain actions that the editors perform in FirstSpirit. Release actions are the only actions that update the release state, all other changes only affect the preview state.

Project without "use release"

If release has been disabled in the FirstSpirit project (See FirstSpirit Documentation about project properties), only preview data states will be transferred to the CaaS. To update data in the release state, a manual data reconciliation needs to be executed using the CaaS Connect schedules.

2.4. Manual data reconciliation

Content changes are automatically synchronized near real-time with the CaaS platform in the background. However, in certain scenarios, it may be necessary to perform a full reconciliation between FirstSpirit and CaaS:

  • Populating the CaaS with existing project data to start a project

  • Updating content after changing project configurations or template/form data definitions

  • Synchronizing data when there are data inconsistencies between FirstSpirit and CaaS platform

Manual full reconciliation of data can be done via the following schedules, which are automatically created with the installation of the CaaS Connect project app.

All CaaS Connect schedules ensure that obsolete documents are removed from the CaaS platform after creating/updating documents.

schedules
Figure 1. Schedules of the CaaS module

The Total Sync schedules only delete obsolete documents that were created or updated with the version 3.38.0 or later. To delete obsolete documents that were created or updated with an earlier module version, the Smart Sync schedules need to be executed once.

Changes to the configuration of these schedules are not persistent, as the schedules are reset to their original state when the project component is installed or updated. If the configuration of these schedules needs to be changed, these changes have to be applied to a copy of the respective schedule.

Depending on the size of the projects and the resulting amount of data, the schedule runtime duration may be very long. This applies in particular to the Total Sync jobs. In addition to the pure number of elements in the FirstSpirit project, factors include the number of languages and, in particular, of image resolutions.

The runtime for the calculation and transfer of resolutions can be significantly reduced by configuring CaaS tags, see chapter Controlling which resolutions are transmitted using the CaaS tag.

2.4.1. Smart Sync

The schedules

  • CaaS Connect - Smart Sync (fast, sends changed data) - PREVIEW and

  • CaaS Connect - Smart Sync (fast, sends changed data) - RELEASE

perform an intelligent full reconciliation of the preview and release data of FirstSpirit and the CaaS platform. This only includes creating or updating outdated documents. The revision information of related FirstSpirit elements is used to identify outdated documents.

In some cases not all documents are updated, even though there were relevant changes in FirstSpirit. To force an update of these documents, the CaaS Connect - Total Sync …​ schedules need to be used.

2.4.2. Total Sync

The schedules

  • CaaS Connect - Total Sync (slow, sends all data) - PREVIEW and

  • CaaS Connect - Total Sync (slow, sends all data) - RELEASE

perform a full reconciliation of the preview and release data of FirstSpirit and the CaaS platform. This includes creating and updating documents of all FirstSpirit elements (as opposed to the Smart Sync schedules), independent of their FirstSpirit revision info.

2.5. Hidden sections

In FirstSpirit it is possible to hide sections. The data of these sections is treated differently depending on the preview or release state.

Sections hidden in FirstSpirit are always part of the preview data, but never included in the release data. The preview data also contains an additional JSON attribute named displayed per section. This indicates whether the section is displayed or hidden and thus whether it is transferred to the CaaS as part of the release data.

Accordingly, the following possibilities for sections arise:

Visibility Part of preview state Value of displayed in preview state Part of release state

Displayed

Yes

true

Yes

Hidden

Yes

false

No

Please note that the displayed attribute is only present in the preview state. In the release state, only visible sections are present and therefore this attribute is not used there.

2.6. Push notifications (change streams)

It is often convenient to be notified about changes in the CaaS platform. For this purpose the CaaS platform offers change streams. This feature allows a websocket connection to be established to the CaaS platform, through which events about the various changes are published.

By default, a crud change stream is provided for each collection created by CaaS Connect. The change stream notifies all connected clients for all Change Events of the types insert, replace, update and delete. It is accessible at <collectionUrl>/_streams/crud. The exact definition of the change streams can be accessed at any time in the collection metadata.

More information on using change streams is available in the CaaS platform documentation.

2.7. Indexes

To query documents from CaaS platform, filters can be used that specify criteria for the documents to be returned. To speed up filter queries on frequently used document attributes, various indexes are set up on some collections created by CaaS Connect. Information on existing indices can be retrieved under <collectionUrl>/_indexes/.

The following indexes are set up in the collections preview.content and release.content:

  • idx_identifier_lang_country with the attribute combination identifier, locale.language and locale.country

  • idx_entity_lang_country with the attribute combination entityType, locale.language and locale.country

  • idx_fstype_lang_country with attribute combination fsType, locale.language and locale.country

  • idx_route with the document attribute route

  • idx_routes_route with the document attribute routes.route

  • idx_changeinfo_lastsynced with the document attribute changeInfo.lastSynced

The order of the index fields is relevant. Please use the database documentation to ensure that your filter queries are designed in such a way that the indexes are used.

More information on indices is available in the CaaS platform documentation.

2.7.1. Create your own indices

You can create your own indexes using the REST API of CaaS platform. The following information is required for this:

  • an authorized API key

  • a collection URL

  • an index name

  • an index body

To simplify the creation of an index, CaaS Connect also offers the executable CaasConnectCreateIndexExecutable. This only requires the specification of the index name and its body; the remaining parameters are determined from the calling context.

An example use for the executable are FirstSpirit generations. It can be used within generations in script actions.

#Executable class
com.espirit.caasconnect.executable.CaasConnectCreateIndexExecutable

Example parameter configuration of a script action in an FirstSpirit generation

name value

indexName

idx_page_lang

indexBody

{ “keys”: { page.uid": 1, ‘locale.language’: 1 } }

If you pass the parameters from the table above in the properties of a generation, the following index is created when the generation is executed:

{
    v: 2,
    key: {
        page.uid: 1,
        locale.language: 1
    },
    _id: idx_page_lang
}

More information on creating indexes can be found in the Documentation of RESTHeart.

If the index creation takes longer due to very large amounts of data in CaaS, an error is logged. It is possible that the index creation is still successful after more than an hour.

2.8. FirstSpirit GraphQL API

The CaaS Connect module supports generating and provisioning the FirstSpirit GraphQL API since version 3.25.10. As of version 3.59.2 this feature is stable and generally available.

The FirstSpirit GraphQL API enables querying FirstSpirit content with GraphQL (including filtering, sorting and pagination). The capabilities for querying content using this API don’t differ much from the REST API collection endpoints of the CaaS platform of a FirstSpirit project.

2.8.1. URL endpoints

The CaaS Connect module provides a GraphQL API for the preview and release content. The URL endpoints of the API consist of the following elements:

  • Base URL of the CaaS platform + /graphql path
    e.g. https://my-caas-dev.e-spirit.cloud/graphql/..

  • Tenant ID
    e.g. ../my-caas-dev/..

  • Project GID + preview/release suffix -preview-documents or -release-documents
    z.B. ../631e4786-0dc3-4db6-bad8-adaad685944a-preview-documents

The following URL shows an example of the complete URL of the FirstSpirit GraphQL API for the preview content of a project:

More information on querying data via the GraphQL API can be found in the chapter GraphQL API of the CaaS platform documentation.

The configuration dialog of the project component shows an overview of all FirstSpirit GraphQL API URLs of the project (see chapter Project component of the administrator documentation).

The tutorial Quickstart: FirstSpirit GraphQL API serves as a quick introduction for using the FirstSpirit GraphQL API.

2.8.2. Schema

The FirstSpirit GraphQL API schema is generated dynamically based on the data model of the project and is very similar to the data format of the JSON documents (see chapter Data format).

Query fields (entry points)

The generated schema contains at least one query field for querying multiple documents (collection field) of the following content types.

  • PageRef

  • Dataset

  • Media

  • ProjectProperties

  • GCAPages

Each query field also allows filtering, sorting, and paging the results using the arguments filter, sort, skip and limit.

Only JSON documents (using GraphQL variables) are accepted for the filter and sort arguments.

The format of the value corresponds to that of the filter or sort query parameter of the CaaS platform REST API (see chapter Use of filters of the CaaS platform documentation).

Automatic resolution of references

There is a significant difference to the format of JSON documents for all form fields that contain references to other documents. Specifically, this affects the following form field types:

  • FS_REFERENCE (only PageRef and Media references)

  • FS_DATASET

  • FS_INDEX (only DatasetDataAccessPlugin)

The following fields of these types do not contain the raw data of the reference, but instead contain the data of the referenced documents (by resolving the references).

  • value for FS_REFERENCE

  • value.target for FS_DATASET

  • value[].value for FS_INDEX

2.8.3. API deployment/provisioning

Unlike the REST API of the CaaS platform, which is provisioned independently of the CaaS Connect module, the FirstSpirit GraphQL API is provisioned dynamically by CaaS Connect.

The CaaS Connect module uses the Management API for GraphQL applications of the CaaS platform to provision the GraphQL API.

Initial (automatic) provisioning

The FirstSpirit GraphQL APIs are provisioned for the first time during the service start and after installation/update of the project component, only if the FirstSpirit GraphQL APIs do not yet exist.

Manual provisioning

To provision the APIs manually (e.g., after making changes to the project model), the related schedule entries Deploy FirstSpirit GraphQL API or the executable CaasConnectGraphqlSyncExecutable can be used.

If non-backward-compatible changes have been made to the project’s data model, the schedules and the executable still provision and update the FirstSpirit GraphQL APIs. This can negatively impact consumers of the APIs because it can break queries due to breaking changes in the schema.

The query fields that are created automatically are based on the templates. It is not necessary for data to already be stored for these templates. There is one difference with the GCAPages. Here the queries are only generated for used templates. Therefore, if templates for GCAPages already exist but are not yet used, it is necessary to update the schema when these templates are used for the first time.

3. Hosting of media files

The CaaS Connect module supports several methods to host the binary data of media:

  • Upload to S3 and access via a CloudFront distribution (CloudFront CDN)

    • This is the default in the Crownpeak Cloud.

  • Upload to S3 and access via a S3 REST API

  • Upload to file buckets of the CaaS platform and access via the CaaS REST API.

    • This is the default when no S3 configuration is provided.

The options have different use cases and are therefore explained individually below.

The number of media files that are transferred to the target system is identical for all hosting options. For language-independent media, exactly one binary file is transferred. For language-dependent media, one binary file is transferred for each active language. Additionally, for images the binary data of each resolution is transferred if no CaaS-Tag has been set.

Languages are considered active when the option Generate language is enabled in the project language configuration.

3.1. Upload to S3

This option includes the upload of the media files into a S3 bucket. The binary files are stored within the bucket under the configured path prefix (default is prefix /). The path is also composed of the GID of the project and the path segment /preview, depending on whether the media is in the release or preview state. The rest of the path and the filename of a media file are derived from the Advanced URL of the media.

Example of a S3 object path:

/631e4786-0dc3-4db6-bad8-adaad685944a/preview/FirstSpirit/images/thisisatest.png.

When uploading media files to S3, the files can be accessed either through a CloudFront distribution or directly through the associated S3 REST API endpoint. The following chapters describe these two access options.

3.1.1. Access via CloudFront Distribution

When using a CloudFront distribution to access the media files, the URL to a file is composed of the domain of the CloudFront distribution and the path of the S3 object (described above).

For example, the following URL points to the original resolution of an image of the preview state, which is accessible through a CloudFront distribution that is configured to use the S3 bucket for the domain my-cloudfront-domain.tld.

The following code snippet shows an example of the content of a media document, including the URLs that point to the binary data for each resolution of the image.

If the CaaS-Tag is set in the resolutions settings, only these will also be listed in the resolutionsMetaData object.

Example: JSON of a media document in the preview state
{
    "_id": "3b3fe5b6-9ec1-4e45-84c8-bc6a39d0aa61.en_US",
    "fsType": "Media",
    "name": "thisisatest",
    "displayName": "thisisatest",
    "identifier": "3b3fe5b6-9ec1-4e45-84c8-bc6a39d0aa61",
    "uid": "thisisatest",
    "uidType": "MEDIASTORE_LEAF",
    "fileName": "thisisatest",
    "languageDependent": false,
    "mediaType": "PICTURE",
    "description": null,
    "resolutionsMetaData": {
        "ORIGINAL": {
            "fileSize": 16358,
            "extension": "png",
            "mimeType": "image/png",
            "width": 578,
            "height": 340,
            "url": "https://my-cloudfront-domain.tld/631e4786-0dc3-4db6-bad8-adaad685944a/preview/FirstSpirit/Bilder/thisisatest.png"
        },
        "Teaser": {
            "fileSize": 1192,
            "extension": "png",
            "mimeType": "image/png",
            "width": 111,
            "height": 65,
            "url": "https://my-cloudfront-domain.tld/631e4786-0dc3-4db6-bad8-adaad685944a/preview/FirstSpirit/Bilder/thisisatest_Teaser.png"
        }
    },
    "metaFormData": {},
    "changeInfo": {
        "date": "2021-05-10T10:41Z",
        "revision": 21077
    },
    "locale": {
        "identifier": "EN",
        "country": "US",
        "language": "en"
    },
    "_etag": {
        "$oid": "60990def3542845893b034da"
    }
}

New media URLs are always created by the UrlFactory for the preview state. Already existing stored custom URLs will not be used in preview state!

CloudFront Caching

When changing the binary data of media, its files are not immediately invalidated in the cache of the CloudFront distribution. Instead, an automatic update takes place after a maximum of 15 minutes, provided that the CloudFront distribution is configured to take into account the Cache-Control header from an origins HTTP responses. In the FirstSpirit Cloud this is active by default.

For more information regarding the Cache-Control header, see the S3 object metadata section.

3.1.2. Access via S3 REST API

When accessing media files via the S3 REST API, the URL to a media file is composed of the S3 REST API (virtual hosted endpoint of the bucket) and the path of the S3 object (described above).

For example, the following URL points to the original resolution of an image of the preview state in the S3 bucket my-bucket located in the region eu-central-1.

The following code snippet shows an example of the content of a media document, including the URLs that point to the media data for each resolution of the image.

Example: JSON of a media document in the preview state
{
    "_id": "3b3fe5b6-9ec1-4e45-84c8-bc6a39d0aa61.en_US",
    "fsType": "Media",
    "name": "thisisatest",
    ...
    "resolutionsMetaData": {
        "ORIGINAL": {
            "fileSize": 16358,
            "extension": "png",
            "mimeType": "image/png",
            "width": 578,
            "height": 340,
            "url": "https://my-bucket.s3.eu-central-1.amazonaws.com/631e4786-0dc3-4db6-bad8-adaad685944a/preview/FirstSpirit/Bilder/thisisatest.png"
        },
        "Teaser": {
            ...
            "url": "https://my-bucket.s3.eu-central-1.amazonaws.com/631e4786-0dc3-4db6-bad8-adaad685944a/preview/FirstSpirit/Bilder/thisisatest_Teaser.png"
        }
    },
    ...
}

3.1.3. S3 object metadata

During the upload of media files to the S3 bucket, different metadata attributes are set for the S3 object:

  • Content-Type

    • This attribute is used as the Content-Type response header for requests to the S3 object.

    • It contains the MIME type of the media file (e.g. image/png).

  • Cache-Control

    • This attribute is used as the Cache-Control response header for requests to the S3 object.

    • For the release state it contains the value public, max-age=300, s-maxage=900 by default.

    • For the preview state it contains the value private, no-cache.

3.2. Upload to CaaS and access via CaaS REST API

In this mode, the binary data of media is transferred to CaaS file buckets. The binaries of the media are transferred to either the CaaS file bucket

  • [Project-GID].release.files or

  • [Project-GID].preview.files

depending on whether they are in release or preview state. The file buckets are located in the CaaS database corresponding to the tenant ID. The remaining path and file name of a media file is composed of the FirstSpirit-GID of the medium, as well as language and/or resolution (if the medium depends on language and/or resolution).

The binary data can be accessed via the CaaS REST API. The URL to a media file is composed of the base URL of the CaaS REST API, the path (described above) and the suffix /binary.

The following code snippet shows an example of the content of a media document, including the URLs that point to the media data for each resolution of the image.

Example: JSON of a media document in the preview state
{
    "_id": "3b3fe5b6-9ec1-4e45-84c8-bc6a39d0aa61.en_US",
    "fsType": "Media",
    ...
    "resolutionsMetaData": {
        "ORIGINAL": {
            "fileSize": 16358,
            "extension": "png",
            "mimeType": "image/png",
            "width": 578,
            "height": 340,
            "url": "https://my-caas-url.tld/defaultTenant/e54cb80e-1f9c-4e8d-84b8-022f473202eb.preview.files/f6910b22-6ae8-4ce1-af45-c7b364b3117a.ORIGINAL/binary"
        },
        "Teaser": {
            ...
            "url": "https://my-caas-url.tld/defaultTenant/e54cb80e-1f9c-4e8d-84b8-022f473202eb.preview.files/f6910b22-6ae8-4ce1-af45-c7b364b3117a.Teaser/binary"
        }
    },
    ...
}

3.3. Controlling which resolutions are transmitted using the CaaS tag

By optionally assigning the CaaS tag, it is possible to control which resolutions are subsequently transferred to a file bucket or S3 bucket during a generation.

add resolution tag
Figure 2. Configuration dialog of a new tag

In the following example, only three resolutions are transmitted to the CaaS.

resolution list
Figure 3. listing of the project resolutions

If no CaaS tag is configured in ServerManager for the given project, corresponding binary data will be transferred by default for all resolutions present in the project.

More information about tagging resolutions can be found in the FirstSpirit documentation for administrators.

Please note that previously transferred binary data is not removed from CaaS by subsequent changes to the resolution tag.

Additionally, a change in the CaaS tags will not automatically update the CaaS data, you have to execute the synchronization manually.

When images are transferred to the CaaS, FirstSpirit calculates all resolutions and stores them in a cache. As long as this cache is not yet filled, the runtime of the event processing and the sync jobs, especially during their initial execution, is extremely delayed. This situation can be counteracted by setting the CaaS tag described here.

Also, when exporting projects, the option "Export automatically calculated image resolutions" should remain activated so that the resolution cache is already filled after the import.

3.4. URL Customization (CaaS Connect SaaS)

The CaaS Connect SaaS offering delivers media files through a CloudFront domain (*-media.e-spirit.cloud) in a standardised format (see Access via CloudFront Distribution). If a different URL format is required, the consumers of the CaaS API can generate URLs using the required format and use the custom URLs for further processing. Additionally, a server component is needed for rewriting or redirecting the requests to these custom URLs. The following chapter describes the process of creating custom URLs step by step using examples.

CaaS API Consumer

Consumers of the CaaS API can use the attribute seoRoute of media documents to create custom URLs.

Example: JSON content of a picture document in the preview data
{
    "_id": "3b3fe5b6-9ec1-4e45-84c8-bc6a39d0aa61.en_US",
    "fsType": "Media",
    ...
    "resolutionsMetaData": {
        "ORIGINAL": {
            "fileSize": 16358,
            "extension": "png",
            "mimeType": "image/png",
            "width": 578,
            "height": 340,
            "url": "https://my-customer-name-media.e-spirit.cloud/631e4786-0dc3-4db6-bad8-adaad685944a/preview/FirstSpirit/Images/thisisatest.png",
            "seoRoute": "/FirstSpirit/Images/thisisatest.png"
        },
        ...
    },
    ...
}

Using string concatenation, the seoRoute path can be appended to any domain (and optionally an additional path prefix). The following example appends the seoRoute path to a domain (without an additional path prefix):

https://en-us.my-custom-domain.tld + /FirstSpirit/Images/thisisatest.png

Server

To be able to use your custom URLs a server component is needed which rewrites incoming requests, e.g. using reverse proxying, or redirects requests, e.g. using URL redirection.

The following configuration example configures an NGINX server to rewrite requests based on the requested hostname (name-based virtual hosting using URL rewrites). More specifically, all requests for the hostname en-us.my-custom-domain.tld that target the preview data of a FirstSpirit project with UUID 631e4786-0dc3-4db6-bad8-adaad685944a (which essentially equals the path /631e4786-0dc3-4db6-bad8-adaad685944a/preview) are redirected.

Example: Partial content of a NGINX configuration en-us.my-custom-domain.tld.conf
server {
    listen              443 ssl http2;
    listen              [::]:443 ssl http2;
    server_name         en-us.my-custom-domain.tld;

    # SSL
    ssl_certificate     /etc/nginx/ssl/en-us.my-custom-domain.tld.crt;
    ssl_certificate_key /etc/nginx/ssl/en-us.my-custom-domain.tld.key;

    # security
    include             nginxconfig.io/security.conf;

    location / {
        proxy_pass https://my-customer-name-media.e-spirit.cloud/631e4786-0dc3-4db6-bad8-adaad685944a/preview/;
        include    nginxconfig.io/proxy.conf;
    }

    # additional config
    include nginxconfig.io/general.conf;
}

# HTTP redirect
server {
    listen      80;
    listen      [::]:80;
    server_name .en-us.my-custom-domain.tld;
    return      301 https://en-us.my-custom-domain.tld$request_uri;
}

This is example is NOT COMPLETE and is solely used for explaining the name-based virtual hosting using URL rewrites. Additional NGINX configuration (e.g., security headers, proxy configurations, etc.), that are needed for running the server in production are NOT part of this example.

This example uses an NGINX server as a reverse proxy for rewriting requests. When a similar approach is chosen for production, you need to be aware that the advantages of the Crownpeak Technology GmbH CloudFront CDN like caching and edge locations are only available when running the server in an edge computing network. Alternatively, the server instance(s) should be located as close as possible to the CloudFront edge location that would receive the user traffic.

Additionally, be aware that the advantages of the Crownpeak Technology GmbH CloudFront CDN will work only partially when running the URL redirect server in a different CDN network (i.e. not CloudFront CDN). There are multiple ways to run a server in the CloudFront CDN (e.g., using a CloudFront Distribution or Lambda@Edge).

4. Troubleshooting: Known issues

4.1. Errors during full reconciliation schedule when transmitting documents for project settings page

The error ReferenceNotFoundException: No template defined for project properties can occur during a full reconciliation schedule run when there is no project settings template defined in the project configuration.

This issue was fixed with FirstSpirit version 2023-04 and can be resolved by updating the FirstSpirit server or by setting a project settings template in the project configuration.

5. Tutorials

5.1. Quickstart: FirstSpirit GraphQL API

This guide describes how to query FirstSpirit content using the FirstSpirit GraphQL API. It covers defining a GraphQL query and expanding it step by step to demonstrate the most important features of FirstSpirit GraphQL API.

To complete this guide you need…​

  • access to a FirstSpirit project where the CaaS Connect module is activated,

  • existing content that has already been synchronized with the CaaS platform

  • and a tool or IDE that supports GraphQL.

Guide

  1. Provisioning the FirstSpirit GraphQL API
    First, the latest version of FirstSpirit GraphQL API must be provisioned. To do this, the Deploy FirstSpirit GraphQL API schedules can be executed for the preview and release state.

  2. URL of the API endpoint and API key
    For the next steps you need both the URL of an API endpoint and an API key with read permissions. These can be copied from the project component.

  3. Query basic attributes of a PageRef

    The following GraphQL query needs to be sent to the URL from the previous step of an API endpoint of the FirstSpirit GraphQL API using a tool or IDE that supports GraphQL.

    To authenticate the request, the API key from the previous step must be specified in the Authorization header using the Bearer authentication scheme.

    The following query fetches basic attributes of the PageRef content.

    GraphQL query
    {
      pageRefs {
        displayName
        locale {
          identifier
        }
      }
    }
    JSON response body
    {
      "data": {
        "pageRefs": [
          {
            "displayName": "Produkt Landingpage",
            "locale": {
              "identifier": "DE"
            }
          },
          {
            "displayName": "Product Landingpage",
            "locale": {
              "identifier": "EN"
            }
          }
        ]
      }
    }
  4. Query authored content
    In addition to the basic attributes of various content, authored content can also be queried.

    The following query fetches the headline of all PageRef documents of type LandingPage as an example.

    GraphQL query
    {
      pageRefs {
        displayName
        locale {
          identifier
        }
        page {
          ... on LandingPage {
            formData {
              pt_headline {
                value
              }
            }
          }
        }
      }
    }
    JSON response body
    {
      "data": {
        "pageRefs": [
          {
            "displayName": "Produkt Landingpage",
            "locale": {
              "identifier": "DE"
            },
            "page": {
              "formData": {
                "pt_headline": {
                  "value": "Testsieger 2013"
                }
              }
            }
          },
          {
            "displayName": "Product Landingpage",
            "locale": {
              "identifier": "EN"
            },
            "page": {
              "formData": {
                "pt_headline": {
                  "value": "Test winner 2013"
                }
              }
            }
          }
        ]
      }
    }
  5. Filter content
    All query fields also support passing an arbitrary filter via the filter argument.

    In the following query example, the results are filtered so that only English content is returned.

    GraphQL query
    query ($filter: BsonDocument) {
      pageRefs(filter: $filter) {
        displayName
        locale {
          identifier
        }
        page {
          ... on LandingPage {
            formData {
              pt_headline {
                value
              }
            }
          }
        }
      }
    }
    GraphQL query variables
    {
      "filter": {
        "locale.identifier": "EN"
      }
    }
    JSON response body
    {
      "data": {
        "pageRefs": [
          {
            "displayName": "Product Landingpage",
            "locale": {
              "identifier": "EN"
            },
            "page": {
              "formData": {
                "pt_headline": {
                  "value": "Test winner 2013"
                }
              }
            }
          }
        ]
      }
    }
  6. Sort and paginate content
    Finally, the results are sorted and paginated using the arguments sort, skip and limit.

    The results are sorted in ascending order using the attribute page.formData.pt_headline.value.

    GraphQL query
    query ($filter: BsonDocument, $sort: BsonDocument) {
      pageRefs(filter: $filter, sort: $sort, skip: 5, limit: 5) {
        displayName
        locale {
          identifier
        }
        page {
          ... on Product_specialPage {
            formData {
              pt_headline {
                value
              }
            }
          }
        }
      }
    }
    GraphQL query variables
    {
      "filter": {
        "locale.identifier": "EN"
      },
      "sort": {
        "page.formData.pt_headline.value": 1
      }
    }

More information on the format of the filter and sort arguments can be found in the chapter FirstSpirit GraphQL API → Schema.

The CaaS is a product of Crownpeak Technology GmbH, Dortmund, Germany.

Only a license agreed upon with Crownpeak Technology GmbH is valid with respect to the user for using the module.

7. Help

The Technical Support of the Crownpeak Technology GmbH provides expert technical support covering any topic related to the FirstSpirit™ product. You can get and find more help concerning relevant topics in our community.

8. Disclaimer

This document is provided for information purposes only. Crownpeak Technology GmbH may change the contents hereof without notice. This document is not warranted to be error-free, nor subject to any other warranties or conditions, whether expressed orally or implied in law, including implied warranties and conditions of merchantability or fitness for a particular purpose. Crownpeak Technology GmbH specifically disclaims any liability with respect to this document and no contractual obligations are formed either directly or indirectly by this document. The technologies, functionality, services, and processes described herein are subject to change without notice.