Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Research: Submit forms through GraphQL query #10

Closed
chillu opened this issue Nov 3, 2016 · 3 comments
Closed

Research: Submit forms through GraphQL query #10

chillu opened this issue Nov 3, 2016 · 3 comments
Assignees

Comments

@chillu
Copy link
Member

chillu commented Nov 3, 2016

This is a subset of the issue DataObject subclass/extension in queries and mutation. At the moment we're using form schema to construct forms in React, but are submitting them via a standard url encoded POST request. This conceptually overlaps with GraphQL mutations and types.

Issues:

  • Since you can add arbitrarily computed values to any form, we can't assume a 1:1 relationship to a DataObject or GraphQL type based on a DataObject - even though that's the most common use case in CMSMain or ModelAdmin.
  • Forms contain implicit data constraints (by conditionally leaving out fields or marking them as readonly) and explicit form validation. We should transition most of these constraints into the DataObject layer, but there will still be use cases for form-only constraints
  • Data in relationship editors like GridField isn't necessarily related to the main record loaded into the form, so these might need their own data loading logic.
  • We could assemble GraphQL queries on the server and send it down with form schema metadata, but we'll have to perform all the state management of the graphql() HOC ourselves (through client.query())
  • If we separate form submissions from DataObject GraphQL types, we need way for the submission handling to indicate to the client which data has gone stale (either delivering new data in the response, or triggering a fetch from the client). See Update GraphQL models after form submission #14
  • File uploads might pose an issue in GraphQL: The blob contents will be too large for a JS client to efficiently handle this as part of the GraphQL JSON payload. We could implement HTTP multipart handling for this.
@chillu chillu added this to the CMS 4.0.0-alpha4 milestone Nov 3, 2016
@chillu chillu changed the title Submit forms through GraphQL query Researh: Submit forms through GraphQL query Nov 17, 2016
@chillu chillu changed the title Researh: Submit forms through GraphQL query Research: Submit forms through GraphQL query Nov 17, 2016
@wilr
Copy link
Member

wilr commented Nov 24, 2016

I've begun this work and have been evaluating possible solutions to this problem. After discussing and interviewing Ingo I’ve based on research given these assumptions

  1. We want to keep defining forms in PHP.
  2. We want to keep consistent with Form API's such as saveInto

Those are two large assumptions but for now those are holding true. Points 1 - 4 in the above would only be an issue if we dropped those 2 assumptions and moved all form submission handling to GraphQL which is clever but would potentially lose a significant benefit of SilverStripe. Anyho,

Approach 1. FormMutation

Initially, I tested a PoC using a standard FormMutation will be defined by the GraphQL library along with structured types formSubmission, formResult (example https://gist.github.com/wilr/5f39e37d960ebebdf864f1ca8a9ae56c). This works well and rather elegantly however it creates a GraphQL layer over and above Form and would require a large pre-condition:

Currently Forms are built and accessed via controllers (i.e /admin/assets/EditForm/5) and submitting to the URL submits for correct form however, via graphql mutation we lose that routing so we need to be able to initialise the same Form object given some context from the mutation POST. In my PoC the formSubmission included the fully qualified classname of the form in order to recreate it and hand over to it to resolve. There is no easy API for returning a form object from a given URL without going right through handleRequest bootstrap again.

As this approach would require moving permission checking and other logic from controllers to form objects it's deemed too major for 4.0 but likely for 5.0 for CMS forms as it would enforce practises through strict typing such as standard form return types.

I’m not sure it provides any major benefit overall (apart from reducing boilerplate) but introduces complexity behind the scenes. Though, it would allow Form level rules and validation while using strict typing.

Approach 2. Generate GQL direct to model

Ditch Form::httpSubmission entirely for Redux based forms. Each field would be explicitly given an object to map to and a field name. Purest as validation / rules would be on the model level / specific validation would be client side.

Not considered in depth as it would void assumption 2 and result in a significant shift.

Approach 3. As-is++

This approach keeps form submissions exactly how they are and simply adds some functionality to form schema in the way of passing back a list of object keys, fields and values that have changed.

This approach is the preferred for 4.0 as individual forms can opt-in to this API end point. The list of fields modified would be automatically populated based on calls to DataObject::write().

Alternatively we could simply track object Id's that have been modified and do a second graphql query on form response. It's another HTTP round trip but would require less specific change tracking.

TODO

  • Design FormSchema changes to encapsulate what Queries need to be modified (i.e adding / removing records) and what records need to be updated
  • Without a mutation can writeToStore be called to update the store with a given key
  • Design how we'd 'track' changed fields in DataObject::write() to pass back to the form to update the form Schema if that's the approach we want to take.

References

@chillu
Copy link
Member Author

chillu commented Nov 24, 2016

I've created a separate issue for sorting out the PHP form API required to implement Approach A: silverstripe/silverstripe-framework#6334

@chillu
Copy link
Member Author

chillu commented Nov 24, 2016

Research closed in favour of Approach A, with client-side work defined in Submit forms through GraphQL, and more work defined in Update GraphQL models after form submission

unclecheese pushed a commit to open-sausages/silverstripe-graphql that referenced this issue Jan 9, 2018
unclecheese pushed a commit to unclecheese/silverstripe-graphql that referenced this issue Jan 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants