First-party GraphQL Support#96
Conversation
|
Thanks @mattstein We'll review and work on getting this included shortly. |
|
Nice work on this PR! Is there any way we can resolve these conflicts, then possibly get this merged? Or have a different implementation of it that would allow GraphQL to return the object properties. It would be nice to use the plugin, but without proper GraphQL support, I will end up using something else. Perhaps a Super Table field would work in our case (location addresses). Also, we would gladly pay a small fee for the use of this plugin, as well. It really is a nice plugin, it just needs to be updated to work with GraphQL. Thanks! |
|
@nickroberts We're currently catching up on some outstanding Craft 3.4 bugs and once we feel like everything is in a good place with Craft 3.4 support we'll be turning our attention to GraphQL support. We'll update this thread once we do. |
|
Sounds great! |
This PR adds native GraphQL support for fields that didn't already resolve neatly as strings: Address, Notes and PredefinedDate. It may satisfy #93 depending on how elaborately you'd like to support GraphQL.
Changed Behavior
Previously, querying a Notes or Predefined Date field would return
nullin each case. This instead returns the rendered note and date respectively. The date is formatted according toFormatDateTime::DEFAULT_FORMATviacraft\gql\types\DateTimesince that's how Craft returns its ownDateTimevalues via GraphQL.The Address field was previously returning the complete address as formatted markup. This registers a new GraphQL object entity so that Sprout Fields can make each Address nugget available individually.
Current Behavior (without PR)
Query (each
sprout*handle being a custom field type):{ entries { ... on test_test_Entry { sproutAddress sproutEmail sproutPhone sproutPredefined sproutGender sproutName sproutNotes sproutPredefinedDate sproutRegularExpression sproutUrl } } }Response:
{ "data": { "entries": [ { "sproutAddress": "<p translate=\"no\">\n<span class=\"address-line1\">12345 Balboa Parkway</span><br>\n<span class=\"locality\">Los Angeles</span>, <span class=\"administrative-area\">CA</span> <span class=\"postal-code\">92654</span><br>\n<span class=\"country\">United States</span>\n</p>", "sproutEmail": "lucille.bluth@hotmail.com", "sproutPhone": "+1 555-555-5555", "sproutPredefined": "test-fields", "sproutGender": "female", "sproutName": "Lucille Bluth", "sproutNotes": null, "sproutPredefinedDate": null, "sproutRegularExpression": ".*", "sproutUrl": "https://recurringdevelopments.com/", } ] } }Updated Behavior (with PR)
Query:
{ entries { ... on test_test_Entry { sproutAddress { address1 address2 locality administrativeAreaCode postalCode countryCode } sproutEmail sproutPhone sproutPredefined sproutGender sproutName sproutNotes sproutPredefinedDate sproutRegularExpression sproutUrl } } }Response:
{ "data": { "entries": [ { "sproutAddress": { "address1": "12345 Balboa Parkway", "address2": "", "locality": "Los Angeles", "administrativAreaCode": "CA", "postalCode": "92654", "countryCode": "US", }, "sproutEmail": "lucille.bluth@hotmail.com", "sproutPhone": "+1 555-555-5555", "sproutPredefined": "test-fields", "sproutGender": "female", "sproutName": "Lucille Bluth", "sproutNotes": "<p>Always leave a note.</p>", "sproutPredefinedDate": "2019-11-14T10:11:39+00:00", "sproutRegularExpression": ".*", "sproutUrl": "https://recurringdevelopments.com/", } ] } }How it Works
Each modified field type needed to clarify how it should be reduced to scalar types for GraphQL. Craft automatically tries—and mostly succeeds with the rest of the field types—to get and use the string value of a given field. Each adjustment here implements
getContentGqlType()on the respective field class.Predefined Date is the simplest, returning Craft's
GqlDateTimeType::getType().Notes is more atypical for a field type. It returns a string type and uses a
resolveparameter that provides thenotesproperty as that string.Address returns an object with properties that map to strings. To do this, it creates and registers a new object type, each property mapping directly to those that already exist on the field's address pieces. Note that this type is re-used by
GqlEntityRegistry::getEntity()if it already exists, for healthy performance.Limitations
Reasons you may not want to merge immediately:
If you have any questions, objections or requests let me know!