Build React forms based on GraphQL APIs.
Easy form creation from GraphQL mutations with <ApolloForm>
Background
Like everybody in the “React world”, I heavily used redux-form
on my current company big SPA, even after the migration from REST API to GraphQL API.
We were using a custom form framework that :
- generate a
redux-form
based on a JSON-based description of fields - validate data against a custom validation API endpoint
- call a user-defined callback for saving data
⠀
⠀
⠀
⠀
⠀
Example of code for the User form:
This framework had many drawbacks:
- verbose: list all fields of the described object was repetitive
- redundant: need to mix submitted data and call mutation by hand
- duplicated logic: need to call the API to validate data before submitting
- extensibility: class based declaration(💣),
hard to customise or extends rendering since it’s not component based
➡️ It’s here that comes ApolloForm
. 🚀
⠀
<ApolloForm>
⠀
ApolloForm
design goals are:
- API/Client Interoperability:
map your forms to existing mutations with ease - Simplicity: only specify what you need, in a functional way
- Extendable: Remove and replace anything if you need
- State management and validation:
drop redux state and use form local state
The idea of ApolloForm
comes from the awesome react-jsonschema-form
framework from Mozilla.
⠀
Basically, react-jsonschema-form
helps to build forms using JSON Schema.
This is extremely powerful because it avoids duplication by :
- describing data using the JSON Schema standard
- using
ajv
lib to validate data against the JSON Schema on client side !
Want to know more about react-jsonschema-form
?
➡️ read “Understanding “react jsonschema form” in 2 minutes”
⠀
react-jsonschema-form
provides 2 of the 4 design goals:
- Extendable, with the fields and widgets system.
- State management and validation,
handled with local state and local validation usingajv
.
ApolloForm
bring the last 2 key features:
- API/Client Interoperability: generate the form JSON Schema from a mutation definition
- Simplicity: provide some helpers to avoid the complexity of JSON Schema and enhance the extensibility of
react-jsonschema-form
.
User Form 2.0 with ApolloForm
With the following GraphQL Schema (excerpt):
Here how looks the User Form with <ApolloForm>
:
How it works
⠀
First, generate the GraphQL API corresponding JSON Schema
react-apollo-form
expose a bin script to generate those files –
using awesome library apollo-codegen
.
react-apollo-form fetch-mutations <graphqlEndpointUrl> <outputDir>
This will generate 3 files:
schema.json
➡️ the GraphQL API Introspection datamutations.d.ts
➡️ definesApolloFormMutationNames
, a union type of all mutations namesapollo-form-json-schema.json
➡️ a JSON Schema describing all types, Query and Mutations available, we call it “mutations global jsonSchema”
⠀
Then, configure a “Form component” based on those configuration files
For this, we use the factory function configure()
, that needs:
- a
ApolloClient
- the “mutations global jsonSchema” object
configure()
then return a configured <ApolloForm>
component.
And here’s how its works at runtime:
Conclusion
ApolloForm
, backed on react-jsonschema-form
ensure a distinct separation between:
- Data structure: what kind of data and validation are exposed
config={}
- UI structure: how we want to display this data
ui={}
This is a great deal, in term of architecture/design. ✨
Want to give a try? 🚀
This article only cover the basic features of <ApolloForm>
, you can discover:
- Theming
- Building a form without mutation
- Rendering customisation with render props
- Conditionals fields for advanced forms
- What’s next? 🔀 Swagger & Relay support, feature requests? …
↪️ If you want to play with <ApolloForm>
, just give a look at
“Getting started : How to build a GraphQL form in 5 minutes”.
I hope you like the idea of GraphQL based React forms,
feel free to share any ideas on the issue tracker! 👨🚀
This story is published in Noteworthy, where 10,000+ readers come every day to learn about the people & ideas shaping the products we love.
Follow our publication to see more product & design stories featured by the Journal team.