Was this page helpful?

Functions

Table of contents

What are Functions?

Functions are serverless workloads that run on Contentful’s infrastructure to provide enhanced flexibility and customization. You can use Functions to:

  • connect to external systems and enrich the response of requests issued through Contentful's GraphQL API, or
  • filter, transform, and handle events coming from Contentful without having to set up your own backend.
Note: This feature is currently only supported by our GraphQL API. To learn more about GraphQL in Contentful, see the Getting started with GraphQL documentation. This feature is not yet available for EU data residency.

Use case: External References

At times, you may need to reference content stored outside of Contentful. With External references you can seamlessly integrate your custom code within the delivery context. Some of our marketplace apps, such as Shopify, commercetools and Cloudinary, already have out-of-the-box support for this feature. For more information, see the External references page.

External references examples

Function Command Description
function-potterdb npx create-contentful-app@latest
--example
function-potterdb
This example serves as a Function for Contentful. It is designed to proxy GraphQL requests to PotterDB.
function-potterdb-rest-api npx create-contentful-app@latest
--example
function-potterdb-rest-api
This example also serves as a Function but is specifically tailored for wrapping a REST API in a GraphQL response. It's useful when you have a RESTful service, and you want to provide a GraphQL interface for it in your Function.
function-mock-shop npx create-contentful-app@latest
--example
function-mock-shop
This Function example uses Mock Shop API which is a fake e-commerce platform built by Shopify. You can also follow the our tutorial for this example.

The following diagram displays the Function request flow:

Functions request flow

The Function event handler can parse two different types of events:

  1. GraphQL field mapping event – the information returned by your function for this event is used to decide which GraphQL type is exposed on the additional _data field.
  2. GraphQL query event - your function will receive this event whenever we want to get data for a GraphQL request. This includes introspection queries.

The Function event handler can return two different types of responses:

  1. Field mapping response.
  2. Query response.

Each field that is configured with Functions, must map to a schema. We need to know the relation with the field and the corresponding GraphQL type in the Function. Therefore, the field mapping response should include a field mapping for each field.

Given the schema below:

type Query {
  product(id: String!): Product
}

type Product {
  title: String!
  description: String
  inStock: Int!
}

Here is the typing for GraphQLFieldMapping:

type GraphQLFieldTypeMapping = {
  contentTypeId: string
  fieldId: string
  graphQLOutputType: string
  graphQLQueryField: string
  graphQLQueryArguments: Record<string, string>
}

GraphQLFieldTypeMapping would have the following values for the product field:

Value Description
contentTypeId: 'Shop' Content type ID that includes the field with Resolve content on delivery checkbox enabled.
fieldId: 'product' Field ID that includes the field with Resolve content on delivery checkbox enabled.
graphQLQueryField: 'product' Field name in the query object of the given GraphQL schema.
graphQLOutputType: 'Product' The GraphQL type that you want to attach to our _data field.
graphQLQueryArguments: { id: '' } Arguments that match for the field. id matches the argument for the product field and the empty value states that the data from the field should be passed as is.

The information coming in the event.fields array in the field mapping event is driven by the annotations that are added to the field once you enable Resolve content on delivery checkbox.

To get the schema, we run an introspection query that ends up triggering the graphql.query event. Note that this might happen repeatedly, and not when you install an app.

Use case: App Events

Note: App Event functions are in beta. Sign up for early access here.

Subscribing to App Events unlocks powerful hooks into the content lifecycle, but it requires setting up and hosting a backend app. Using Functions with App Events, developers gain access to a fully managed, scalable, and resilient serverless workflow that eliminates the need for custom backend infrastructure.

Functions streamline interaction with App Events, simplifying the process for developers. They can be used to:

  • orchestrate intricate workflows across various services.
  • perform resolution and hydration of data from external systems.
  • implement custom logic to manage event-triggered builds or cache invalidation.

The following App Event functions are supported:

  • Filter functions that run before any other processing, and are used to determine whether events are triggered or discarded.
  • Transformation functions that run before request signing, and are used to modify the headers and body of the request.
  • Handler functions that can be used as the target of the event, as opposed to targeting a URL. All three function types receive the same headers and body as a traditional App Event does.

App Event Function Examples

Function Command Description
function-appevent-filter npx create-contentful-app my-app
--function
appevent-filter
This example showcases how Functions can be used to select which App Events are triggered.
function-appevent-transformation npx create-contentful-app my-app
--function
appevent-transformation
This example portrays how a Function can enrich the App Event request body with information from an external system.
function-appevent-handler npx create-contentful-app my-app
--example
appevent-handler
This example exhibits proxying an App Event out to multiple external services.

Limitations

  • There is a limit of 50 Functions per one custom Contentful app definition.
  • A Function has a maximum execution time of 5 seconds.
  • Functions are only available for private apps.
  • You can have 50 Functions per custom Contentful App defined.
  • External References run only for uncached requests.
  • External references can only be used with short Text or JSON object field types.
  • External references allow you to integrate with external GraphQL APIs. You can also integrate with external REST APIs, but you have to provide your own GraphQL server implementation. For more information on the REST API implementation, see our PotterDB for REST example.
NOTE: In the event your Function times out, we will not retry again.

Get started with Functions

To build a custom Function:

  1. Start by creating a custom Contentful App. To quickly scaffold a new app with TypeScript support and an example Function, run the following command: npx create-contentful-app@latest <app-name> --function <function-type>. Replace <app-name> with your desired app name, and replace <function-type> with one of the following:
    • external-references
    • appevent-filter
    • appevent-transformation
    • appevent-handler
  2. If building an External references Function, define your schema.
  3. Build your app by running the following command: npm run build.
  4. Upload your app to Contentful by running npm run upload.
  5. Install your app.

At this point, your custom Function is ready to be used within Contentful, and you have just a few more steps left to enable it. Use the following external references setup procedure when building External references Functions, or the app event functions setup steps when building App Event Functions.

External references setup

If building an External references Function, follow these steps to link it to a content type and use it in a GraphQL request:

  1. Create a content type.

IMPORTANT: To use the Functions, make sure you select your app while configuring your content type and enable the Resolve content on delivery checkbox.

Screenshot of Functions

  1. Create an entry.
  2. Make a GraphQL request. You can use the GraphQL Playground app to try this easily.
query {
  topicProduct(id: "ENTRY_ID") {
    myField
    myField_data {
      foo
    }
  }
}

Within the topicProduct content type, there is a field named myField which represents the content within topicProduct. The query also contains a reference to myField_data. The _data suffix in the field name implies that it is intended for use with functions. Functions are custom functions that retrieve content, and the _data suffix is a convention to signify that the field is designed to access content fetched through these functions. The foo type comes from the schema used in the function implementation.

Here is an example Response with resolved data from the function:

{
  "data": {
    "topicProduct": {
      "myField": "this is a test",
      "myField_data": {
        "foo": "hello world"
      }
    }
  }
}

App Event Functions setup

If building an App Event function, follow these steps to link it to an App Event Subscription:

  1. Navigate to the Events tab of your app definition in the organization settings, and ensure the Enable events option is active for your app.
  2. Select the topics you would like to trigger your function.
  3. Use the dropdown menus on this page to select the functions you would like to invoke. You may select one filter function, one transformation function, and one handler function.
  4. Click the save button in the top right to preserve your selections.

NOTE: You can also perform these actions via the Content Management API (CMA) by issuing a request to update or subscribe to events.

  1. Trigger a targeted action within Contentful to invoke your function. For example, if you subscribed to the Entry.create topic, create an entry to invoke your function.

Inspect Function invocations and logs

To get a better understanding of how your function is performing, you can inspect the invocations and log output. To inspect the invocations and log output:

  1. Navigate to the App configuration page in the Contentful web app.
  2. Select the Functions tab.
  3. Open the menu of the function you want to inspect and select View logs.

Function logs menu item

  1. On the Function logs page, select the space and environment the app is installed in. A list of all the function invocations in the selected space and environment is displayed.
  2. Click on an invocation to see the log output of the function.

Function invocations table

  1. At the top of the drawer, expand the Event section to see the event that triggered the function. Below that, the log output of the function is displayed.

NOTE: The log severity is based on the log method used in the function. console.log will show severity info, console.warn will show severity warn, and console.error will show severity error. You can use this to quickly find relevant logs in the table that lists all the invocations.

Function invocation logs

Feedback

Our Product team highly welcomes feedback for all our features. To share your feedback, fill in this form.