cortex-cms / cortex

:pencil: A headless, multitenant dynamic content platform powered by Rails, GraphQL and Elasticsearch
https://docs.cortexcms.org/
Apache License 2.0
32 stars 6 forks source link

GraphQL + ElasticSearch #533

Open toastercup opened 6 years ago

toastercup commented 6 years ago

JIRA:

https://careerbuilder.atlassian.net/browse/CE-307 (GraphQL) https://careerbuilder.atlassian.net/browse/CE-160 (ElasticSearch Infrastructure) https://careerbuilder.atlassian.net/browse/CE-503 (ElasticSearch FieldType Mappings)

MVP Features:

Helpful resources:

toastercup commented 6 years ago

Client-side Resources:

toastercup commented 6 years ago

Particularly relevant; an ElasticSearch query builder DSL: https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-dsl

toastercup commented 6 years ago

graphql-ruby also has its own JS client: http://graphql-ruby.org/javascript_client/overview.html It also supports subscriptions with Apollo Client: http://graphql-ruby.org/javascript_client/apollo_subscriptions.html

toastercup commented 6 years ago

This is what I've been loosely following for dynamically generating the schema for FieldItems: http://graphql-ruby.org/schema/dynamic_schema.html

toastercup commented 6 years ago

We'll be using Rails's built-in API key functionality to authenticate API users: http://api.rubyonrails.org/classes/ActiveRecord/SecureToken/ClassMethods.html

toastercup commented 6 years ago

Good rundown of GraphQL Query core concepts with proper terminology: https://dev-blog.apollodata.com/the-anatomy-of-a-graphql-query-6dffa9e9e747

toastercup commented 6 years ago

This will yield a huge benefit over how I was doing things: http://graphql-ruby.org/types/abstract_types.html

We can now group together a bunch of disparate FieldType ObjectTypes under a FieldItem abstract type, vastly simplifying our implementation and querying interface

toastercup commented 6 years ago

And an invaluable explanation of Interfaces and Unions: https://medium.com/the-graphqlhub/graphql-tour-interfaces-and-unions-7dd5be35de0d

toastercup commented 6 years ago

The approach I'm taking tonight (which should hopefully work) is to dynamically define Fields for all ContentTypes in the entire system, then whitelist access per-user by following this guide's recommendations: http://graphql-ruby.org/schema/limiting_visibility.html

toastercup commented 6 years ago

For a truly clean query interface (dynamic, per-user schemas and fields that don't rely on field hiding), we need to wait for the GraphQL-Ruby author to merge https://github.com/rmosolgo/graphql-ruby/pull/1037. This is almost a complete rewrite of the library that will allow us to pass arguments into an ObjectType definition. Until then, we'll have to make do with a query interface that's a bit more verbose, and is not self-documenting in all places.

toastercup commented 6 years ago

Something nifty I'd found but forgot to link to: https://github.com/karmi/es-rails-example

toastercup commented 6 years ago

And then GraphCMS comes along and blows our API out of the water.. https://graphiql.graphcms.com/simple/v1/swapi

We'll get there, though!

toastercup commented 6 years ago

Decently hefty Rails example: https://github.com/howtographql/graphql-ruby

toastercup commented 6 years ago

Sane structure guideline to help clean up our QueryType: https://m.alphasights.com/graphql-ruby-clean-up-your-query-type-d7ab05a47084

toastercup commented 6 years ago

graphql-ruby 1.8pre has been released, which will allow us to create per-user GraphQL schemas (which will hide irrelevant ContentTypes and Fields): https://github.com/rmosolgo/graphql-ruby/blob/1.8-dev/guides/schema/class_based_api.md

toastercup commented 6 years ago

Partially resolved by #536. Keeping this issue open to plan future refactors and features.