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

Scaffold types and queries from DataObject #9

Closed
chillu opened this issue Oct 31, 2016 · 7 comments
Closed

Scaffold types and queries from DataObject #9

chillu opened this issue Oct 31, 2016 · 7 comments

Comments

@chillu
Copy link
Member

chillu commented Oct 31, 2016

At the moment there's a lot of boilerplate involved in creating GraphQL types (example). Reduce this by inferring data from DataObjects (where types/queries are based on them).

  • Set fields through whitelist
  • Infer field types from DBField (String, Text, Enum, etc)
  • Field name mapping (see Static case insensitive property check definitions #8)
  • Build read queries based on type
  • Allow polymorphism based on interfaces (e.g. a createPage mutation which works with all subclasses of Page)
  • Build create/update/delete queries
  • Build input types for mutation queries
  • Custom field resolvers
  • Custom query resolvers
  • Read queries optionally based on SearchContext definitions
  • Register types and queries with a schema manager
  • Allow extension of definitions (e.g. whitelist a new field added by DataExtension)

See https://github.com/chillu/silverstripe-graphql/issues/8 for a start on an API.

@chillu
Copy link
Member Author

chillu commented Nov 17, 2016

I've discussed this a bit more with @unclecheese, and here's some really rough drafts on how this could look like. Overall, we feel that YAML could provide a good result for most use cases, as long as you can write custom resolver classes. These would be injectable, and implement Extension so they can be augmented by third-party code.

GraphQL:
  Member:
    operations:
      - all: true # implies 'create', 'read', 'update', 'delete'
    fields:
      - Email
      - Fullname
      - Groups # Implicitly creates a "Group" GraphQL type
    resolver: MyGraphQLMemberResolver
  Group:
    operations:
      - read: true #only allow reads
    fields:
      Title
class MyGraphQLMemberResolver extends GraphQLResolver {
  public function resolve($args) {
    $list = Member::get();
    // Optional filtering (could be more succinct through SearchContext)
    if($args['Email'])
    $list = $list->filter('Email', $args['Email']);
    return $list;
  }
  // Alternative to accessing DataObject getters
  public function resolveFullname($obj) {
    return $obj->FirstName . ' ' . $obj->LastName;
  }
}

Alternatively, a more fluent API:

$scaffolder = (new GraphQLScaffolder())
    ->addDataObject('Member')
    ->addOperation('Member', GraphQLScaffolder::READ, [])
    ->addFieldResolver('Member', function($args) {
       $list = Member::get();
      // Optional filtering (could be more succinct through SearchContext)
      if($args['Email'])
      $list = $list->filter('Email', $args['Email']);
      return $list;
    })
    ->setFields('Group', ['Title']);

// Get a TypeCreator for further customisation
$memberType = $scaffolder->getType('Member');
// Add all created types, queries and mutations to a schema (through the Manager API)
$scaffolder->addToManager($manager);

I've found an EZSystems configuration which takes a similar approach: https://github.com/bdunogier/ezplatform/blob/graphql/src/BD/EzPlatformGraphQLBundle/Resources/config/services.yml

@unclecheese
Copy link

I've created some pseudo code for this. Deliberately rough around the edges, since, in all likelihood it's way off. :) Have a look and let me know if this is what you're thinking:

https://gist.github.com/unclecheese/b56833232f521d9873781a4bc4827a2a

@unclecheese
Copy link

Had a chance to work on this over the weekend. Have a look https://github.com/silverstripe/silverstripe-graphql/tree/feature/scaffolding

chillu added a commit to open-sausages/silverstripe-asset-admin that referenced this issue Dec 22, 2016
At the moment this is limited to "read files"
and "create folder". The remaining API endpoints will be
successively moved over to GraphQL.

The GraphQL type creators are likely temporary,
to be replaced with a shorter scaffolding-based version:
silverstripe/silverstripe-graphql#9
silverstripe/silverstripe-graphql#22
silverstripe/silverstripe-graphql#23

RFC at silverstripe/silverstripe-framework#6245
@sminnee
Copy link
Member

sminnee commented Jul 25, 2017

Is this done, now? It seems to be mostly done...?

@unclecheese
Copy link

It would be hard to make the case that it isn't. :)

unclecheese pushed a commit to open-sausages/silverstripe-graphql that referenced this issue Jan 9, 2018
…pdate-archive-warning-msg

ENHANCEMENT Remove item from change sets when it's archived
@pie6k
Copy link

pie6k commented Apr 3, 2018

Maybe you could infer types from class to reduce boilerplate. Something like https://github.com/prismake/typegql

unclecheese pushed a commit to unclecheese/silverstripe-graphql that referenced this issue Jan 27, 2021
unclecheese pushed a commit to unclecheese/silverstripe-graphql that referenced this issue Jan 27, 2021
…3/xss-hollywood

CVE-2019-14272 Sanitise link text for insert modals
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

4 participants