Delivery Functions EAP
Table of contents
What are Delivery Functions?
Delivery Functions are serverless functions that run on Contentful’s delivery infrastructure. Some of our marketplace apps already have out-of-the-box support for External references such as Shopify, Commercetools and Cloudinary. If you want to fetch additional content from different resources, you can use the Delivery functions feature to connect to external systems and enrich the response of the GraphQL request issued through Contentful's GraphQL API.
The following diagram displays the Delivery function request flow:
The delivery function event handler can parse two different types of events:
- 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. - GraphQL query event - your function will receive this event whenever we want to get data for a GraphQL request. This includes introspection queries.
The delivery function event handler can return two different types of responses:
Each field that is configured with delivery functions, must map to a schema. We need to know the relation with the field and the corresponding GraphQL type in the delivery 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.
Limitations
- You can only have one delivery function per custom Contentful App defined.
- A delivery function has a maximum execution time of 5 seconds.
- Delivery Functions run only for uncached requests.
- Delivery Functions are only available for private apps.
Get started with Delivery Functions
To build a custom delivery function:
- Create a custom Contentful App.
- Generate a Content Management API (CMA) Access Token.
- Set up your app. To scaffold a new Contentful app with TypeScript support and a delivery function, run the following command:
npx @contentful/create-contentful-app@latest my-del-fn --typescript --delivery-function
. Note thatmy-del-fn
is the name of your app. You can replace this with your desired name. - Define your schema.
- Add your environment variables (like the CMA token) to an
.env
file in the root of your project. To keep your secrets safe, make sure you include the.env
line in your.gitignore
file. - Build your app by running the following command:
npm run build
. - Upload your app to Contentful by running the following command:
npm run upload-ci
. - Install your app.
- Create a content type.
IMPORTANT: To use the delivery functions, make sure you select your app while configuring your content type and enable the Resolve content on delivery checkbox.
- Create an entry.
- 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 delivery functions. Delivery 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 delivery functions. The foo
type comes from the schema used in the delivery function implementation.
Here is an example Response with resolved data from the delivery function:
{
"data": {
"topicProduct": {
"myField": "this is a test",
"myField_data": {
"foo": "hello world"
}
}
}
}
Examples
Delivery function | Command | Description |
---|---|---|
hosted-delivery-function-potterdb | npx create-contentful-app --example hosted-delivery-function-potterdb |
This example serves as a hosted delivery function for Contentful. It is designed to proxy GraphQL requests to PotterDB. |
hosted-delivery-function-potterdb-rest-api | npx create-contentful-app --example hosted-delivery-function-potterdb-rest-api |
This example also serves as a hosted delivery 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 delivery function. |
Feedback
Our Product team highly welcomes feedback for all our features. To share your feedback, you can fill in this form.