WPGraphQL for Gravity Forms
This FREE plugin from @KellenMace of @harness_up exposes @gravityforms data to WPGraphQL, allowing you to query for forms, fields, entries, and more.
Community Plugin
View Plugin on Github🚀📄 WPGraphQL for Gravity Forms
A WordPress plugin that provides a GraphQL API for interacting with Gravity Forms.
- Join the WPGraphQL community on Slack.
- Supported Fields
- Documentation
- Querying Forms & Entries
- Submit a form
- Updating Entries and Draft Entries
- Deleting Entries and Draft Entries
Overview
Using WordPress as a headless CMS with a separate JavaScript-powered frontend single-page app is an increasingly popular tech stack. Traditionally, REST APIs have been used for the purpose of sending data back & forth between the frontend and backend in setups like this but the REST architecture has its limitations.
Using GraphQL means that if your frontend app needs to fetch data for a number of different resources, all of that data can be fetched from the server with a single request. Your frontend app can even define which fields it requires for each of the resources, giving it full control over which pieces of data are fetched and included in the response.
Fortunately, a GraphQL implementation exists for WordPress - WPGraphQL.
WPGraphQL for Gravity Forms extends the WPGraphQL plugin, allowing frontend apps to interact with the Gravity Forms data stored in a headless WordPress backend. This plugin couples the great forms functionality of Gravity Forms with the powerful WordPress-specific GraphQL implementation that WPGraphQL provides.
Our hope for this open source project is that it will enable more teams to leverage GraphQL for building fast, interactive frontend apps that source their data from WordPress and Gravity Forms.
System Requirements
- PHP 7.4+
- WPGraphQL 1.0.0+
- Gravity Forms 2.4+
- WordPress 5.4.1+
Quick Install
- Install & activate WPGraphQL.
- Install & activate Gravity Forms and any supported addons.
- Download the zip of this repository and upload it to your WordPress install, and activate the plugin.
Supported Features
- Querying forms and entries.
- Submitting forms.
- Creating, updating, and deleting draft entries.
- Updating and deleting entries.
Supported Form Fields
| Field | Querying1 | Updating2 | | ----------------- | -------------------------------------- | ----------------------------------------- | | Address | :heavycheckmark: | :heavycheckmark: | | Captcha | :heavycheckmark: | N/A4 | | Chained Selects | :heavycheckmark: | :heavycheckmark: | | Checkbox | :heavycheckmark: | :heavycheckmark: | | Consent | :heavycheckmark: | :heavycheckmark: | | Date | :heavycheckmark: | :heavycheckmark: | | Email | :heavycheckmark: | :heavycheckmark: | | FileUpload | :heavycheckmark: | :hammer: | | Hidden | :heavycheckmark: | :heavycheckmark: | | HTML | :heavycheckmark: | N/A3 | | List | :heavycheckmark: | :heavycheckmark: | | Multiselect | :heavycheckmark: | :heavycheckmark: | | Name | :heavycheckmark: | :heavycheckmark: | | Number | :heavycheckmark: | :heavycheckmark: | | Page | :heavycheckmark: | N/A3 | | Password | :heavycheckmark: | :hammer: | | Phone | :heavycheckmark: | :heavycheckmark: | | Post Category | :heavycheckmark: | :heavycheckmark: | | Post Content | :heavycheckmark: | :heavycheckmark: | | Post Custom Field | :heavycheckmark: | :heavycheckmark: | | Post Excerpt | :heavycheckmark: | :heavycheckmark: | | Post Image | :heavycheckmark: | :hammer: | | Post Tags | :heavycheckmark: | :heavycheckmark: | | Post Title | :heavycheckmark: | :heavycheckmark: | | Radio | :heavycheckmark: | :heavycheckmark: | | Section | :heavycheckmark: | N/A3 | | Select | :heavycheckmark: | :heavycheckmark: | | Signature | :heavycheckmark: | :heavycheckmark: | | Text | :heavycheckmark: | :heavycheckmark: | | TextArea | :heavycheckmark: | :heavycheckmark: | | Time | :heavycheckmark: | :heavycheckmark: | | Website | :heavycheckmark: | :heavycheckmark: |
1: Supports querying the field and its properties.
2: Supports updating the field.
3: This field is for display purposes only, so there is no need for updating.
4: Captcha fields should be validated before the form is submitted, so it doesn't make sense to handle a server-side update. If you have a use case for when a captcha field should be validated server-side, please submit a Feature Request.
Future Feature Enhancements
- Add support for backwards pagination of lists of entries.
- Add support for updating draft entries with additional form fields.
- Ability to query for lists of draft entries, or both entries and draft entries
- Ability to get the total count for a list of entries.
- Ability to create, update, and delete an individual Gravity Form.
- Create & update integration tests.
Documentation
Querying Forms and Entries
Get a Form and its Fields
The example query below shows how you can get a form and its fields.
The id
input accepts either the Gravity Forms form ID (idType: DATABASE_ID
) or a global ID (idType: ID
).
For formFields
, pass in first:300
, where 300
is the maximum number of fields you want to query for.
Inside of formFields
, you must include query fragments indicating what data you'd like back for each field, as shown below. You'll want to make sure that you have a fragment for every type of field that your form has.
Example Query
Get a List of Forms
The code comments in the example query below shows how you can fetch data for multiple forms at once.
Cursor-based pagination is supported. You can use the first
, last
, before
and after
fields, along with the data inside of pageInfo
and the cursors returned by the API to get each page of forms data.
Filtering is also supported. For the where
field, you can specify a status
to get forms that are active, inactive, in the trash, etc.
Example Query
Get a Single Entry
The example query below shows how you can get a single entry by ID, and data about the fields and their values.
The id
input accepts either the Gravity Forms Entry ID (idType: DATABASE_ID
), or a global ID (idType: ID
). The id
input can also accept the resumeToken
for a draft entry when idType
is set to ID
.
For formFields
, pass in first: 300
, where 300
is the maximum number of fields you want to query for.
Inside of formFields
, you must include query fragments indicating what data you'd like back for each field, as shown below. You'll want to make sure that you have a fragment for every type of field that your form has.
Example Query
Get a Single Draft Entry
The gravityFormsEntry
query supports both entries and draft entries. See "Get a Single Entry" above.
To query a Draft Entry, simply pass the resumeToken
to the input id
field, and set idType
to ID.
Example Query
Get a List of Entries
The code comments in the example query below explain how you can get a filtered list of entries.
The plugin supports first/after cursor-based pagination, but does not yet support before/last pagination.
Example Query
Global IDs vs Database IDs
The id
inputs for Form and Entry queries accepts either the Gravity Forms ID (idType: DATABASE_ID
) assigned to the database, or a Global (base-64 encoded) ID (idType: ID
).
To generate global ID for an object, you encode the name of the GraphQL type, followed by the database ID. This can be done in JavaScript using the btoa()
function like this, where GravityFormsForm
is the GraphQL type and 1
is the form ID:
The example query below shows how you can use a Global ID as your input:
Submit a Form
There are two different ways to submit forms: using submitGravityFormsForm
(which allows you to batch submit all of the field values at once), or by incrementally building a draft entry.
Note: Not all form fields currently support updates. For a list of field types that are currently supported, please review the Supported Form Fields table.
Submit a form with submitGravityFormsForm
The example mutation below shows how you can submit a form.
The submitGravityFormsForm
can also be used to submit draft entries by setting the saveAsDraft
input to true
.
The fieldValues
input takes an array of objects containing the id
of the field, and a value field that is determined by the field type. Most fields use value
, however string arrays values (e.g. MultiSelect, Post Category, etc) use values
, and more complex fields use their own value type. An example of each is included below.
This is an interim solution until the GraphQL Spec adds support for Input Unions.
If the field is updated successfully, the errors
field will be null
, and the entry
in the response will be the newly updated entry object. Depending on whether saveAsDraft
is true
, you will either get the new entryId
or the resumeToken
, with the other value set to null
.
If the field is NOT updated successfully, such as when a field validation error occurs, the entry
object in the response will be null
, and the errors
field will provide data about the error. Example:
Submit a form by building a draft entry incremmentally.
Another way to submit forms is to incrementally build a draft entry. This process may be deprecated and removed in future versions of the plugin.
The submission process works like this:
- Send a
createGravityFormsDraftEntry
mutation to create a new draft form entry. This gives you back theresumeToken
, which is the unique identifier for the draft entry that you need to pass in to all the mutations below. - Send as many "update" mutations (such as
updateDraftEntryTextFieldValue
,updateDraftEntrySelectFieldValue
, etc.) as you need to update the values of the draft entry. - When ready, send a
submitGravityFormsDraftEntry
that turns the draft entry into a permanent entry.
For large forms, #2 on the list above could potentially result in the need to send a large number of "update" mutations to the backend to update form entry field values. Using something like Apollo Client's apollo-link-batch-http is recommended so that your app will be able to send a large number of mutations to the backend all within a single HTTP request to update the draft entry.
Example Mutations
Create a New Draft Entry
The example belows how to create a new draft entry using the createGravityFormsDraftEntry
mutation. If you wish, you can create a new draft entry by cloning an existing entry using the fromEntryId
field.
Update an individual Draft Entry value.
The example below shows updateDraftEntryTextFieldValue
, which can be used for updating the value of a text field. Similar mutations exist for other field types, such as updateDraftEntrySelectFieldValue
, updateDraftEntryAddressFieldValue
, etc. The value
shape is the same as used in the fieldValues
input of submitGravityFormsForm
.
Use the resumeToken
from the createGravityFormsDraftEntry
mutation's response. It is this draft entry's unique identifier.
If the field is updated successfully, the errors
field will be null
, and the entry
in the response will be the newly updated entry, with the new field value.
If the field is NOT updated successfully, such as when a field validation error occurs, the entry
object in the response will be unchanged (the new field value will NOT have been applied), and the errors
field will provide data about the error. Example:
Submit a Draft Entry
Once all updates have been performed, the submitGravityFormsDraftEntry
mutation shown below can be run to submit the draft entry so that it becomes a permanent entry.
The entry
field in the response contains data for the newly created entry.
If the field is updated successfully, the errors
field will be null
, and the entry
in the response will be the newly updated entry.
If the field is NOT updated successfully, such as when a field validation error occurs, the entry
object in the response will be null
, and the errors
field will provide data about the error.
Update an Entry or Draft Entry
You can update an entry with the updateGravityFormsEntry
mutation. This mutation works similarly to submitGravityFormsForm
.
Example Mutation
Updating a draft entry using the updateGravityFormsDraftEntry
mutation follows a similar pattern: :
Example Mutation
Delete an Entry or Draft Entry
You can use the deleteGravityFormsEntry
mutation to delete an entry. The entryId
of the deleted entry will be in the response.
Example Mutation
Similarly, you can use deleteGravityFormsDraftEntry
to delete a draft entry. The resumeToken
of the deleted draft entry will be in the response.