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

Using GraphiQL in your Rails app without this gem #85

Open
connorshea opened this issue Jun 13, 2020 · 7 comments
Open

Using GraphiQL in your Rails app without this gem #85

connorshea opened this issue Jun 13, 2020 · 7 comments

Comments

@connorshea
Copy link

Since the gem hasn't been updated recently, I decided to post this issue in the hopes it helps other people interested in using a newer GraphiQL release.

NOTE: This uses Webpacker, you can accomplish this with Sprockets by essentially doing what the graphiql-rails gem already does, but in your own app. aka, just vendor react and graphiql inside your application.

So now that GraphiQL is at 1.0.0, I wanted to update to it in my app. I don't have a specific guide for this that I'm going to write, but you can take a look at my PR for this and my summary of the changes below. connorshea/vglist#1262

Essentially, I just do this:

  • Remove this gem and its initializer and the route in routes.rb
  • Add graphiql, react, and react-dom to my package.json
  • Make a few updates to my webpacker config.
  • Create a new graphiql JS bundle and include the graphiql and react/react-dom libraries there.
  • Create a new page at /graphiql with no layout and load the graphiql.js pack in it.
  • Use an embedded script tag in the page to set up the GraphiQL instance.
  • Done!

And it'll work in production :) Though, you should make sure to take proper security precautions to make sure the GraphiQL instance isn't abused. (I made some relevant changes for using API tokens here: connorshea/vglist#1329)

I don't have any interest in making a gem to do this, sorry! You'll have to set it up yourself. If someone else wants to try, feel free :D

@tegandbiscuits
Copy link

tegandbiscuits commented Aug 14, 2020

For what it's worth, it's possible to do this setup but pulling from a CDN.

I have this in graphiql/index.html.erb.

<html>
<head>
  <title>GraphiQL</title>
  <link href="https://unpkg.com/graphiql/graphiql.min.css" rel="stylesheet" />
</head>
<body style="margin: 0;">
<div id="graphiql" style="height: 100vh;"></div>

<script crossorigin src="https://unpkg.com/react/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://unpkg.com/graphiql/graphiql.min.js"></script>

<script>
  const graphQLFetcher = graphQLParams =>
    fetch('<%= graphql_path %>', {
      method: 'post',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(graphQLParams),
    })
      .then(response => response.json())
      .catch(() => response.text());
  ReactDOM.render(
    React.createElement(GraphiQL, { fetcher: graphQLFetcher }),
    document.getElementById('graphiql'),
  );
</script>
</body>
</html>

@fintroductions
Copy link

fintroductions commented Aug 19, 2020

Awesome stuff. @connorshea, any suggestions on how to accomplish this in Rails-API mode?
Devise auth tokens + GraphiQL don't play too nicely just yet.

@connorshea
Copy link
Author

@fintroductions sorry for the lack of response, I'm not very familiar with API-only Rails apps unfortunately.

@connorshea
Copy link
Author

@tegandbiscuits FWIW if you load those files from a CDN I strongly encourage you to use Subresource Integrity to make sure that - if the CDN is breached - you won't load malicious files for your users. https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity

@fintroductions
Copy link

fintroductions commented Dec 17, 2020 via email

@cowholio4
Copy link

@tegandbiscuits thanks for the example. i added the subresource integrity fields suggested by @connorshea And added support for CSRF tokens.

I have this in show.html.slim

html
  head
    ==csrf_meta_tags
    link(
        href="https://unpkg.com/graphiql@1.8.8/graphiql.min.css"
        rel="stylesheet"
        integrity="sha384-wsOzV0Eph4ZUUJS3E5lWAGWDmvPwKGlSAbUqoAxGs/4Xbiu5go013CHeyiHviRjk"
        crossorigin="anonymous"
    )

  body style="margin: 0;"
    #graphiql style="height: 100vh;"

script(
    crossorigin="anonymous"
    src="https://unpkg.com/react@18.0.0/umd/react.production.min.js"
    integrity="sha384-3fvehj2TEwajh8B8aLpPfx4Ea4bzuasHai/dxAyVlV2uoAcpu9mqz+lVRhBB/YFf"
)
script(
    crossorigin="anonymous"
    src="https://unpkg.com/react-dom@18.0.0/umd/react-dom.production.min.js"
    integrity="sha384-dDaAwdTa5kDnVQlxu7h9UFJ4lR4NIxDNgG+/6iRqTRWhYny4iDtL+t+4qObQVtZ/"
)
script(
    crossorigin="anonymous"
    src="https://unpkg.com/graphiql@1.8.8/graphiql.min.js"
    integrity="sha384-j7sKHA2Xh03DItLy//iDOH3EXXcIb8TZ4SmCIkPjdVZorF1a40xA9xK90NdDJGNg"
)
javascript:
    const graphQLFetcher = graphQLParams =>
        fetch('/graphql', {
        method: 'post',
        headers: { 'Content-Type': 'application/json', "X-CSRF-Token": "#{form_authenticity_token}"},
        body: JSON.stringify(graphQLParams),
    })
        .then(response => response.json())
        .catch(() => response.text());
    ReactDOM.render(
        React.createElement(GraphiQL, { fetcher: graphQLFetcher }),
        document.getElementById('graphiql'),
    )

@connorshea
Copy link
Author

I forgot I made this issue :D It's worth noting that - for whatever reason - GraphiQL's most recent minor release breaks my setup (it just won't load the component so the page is blank). graphiql 1.7.1 works fine but 1.8.x doesn't.

If anyone runs into this problem using my setup, you could try downgrading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants