rmosolgo / graphiql-rails

Mount the GraphiQL query editor in a Rails app
MIT License
447 stars 135 forks source link

Using GraphiQL in your Rails app without this gem #85

Open connorshea opened 4 years ago

connorshea commented 4 years ago

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. https://github.com/connorshea/vglist/pull/1262

Essentially, I just do this:

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: https://github.com/connorshea/vglist/pull/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 commented 4 years ago

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 commented 4 years ago

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 commented 3 years ago

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

connorshea commented 3 years ago

@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 commented 3 years ago

Brilliant, thanks. Much appreciated.

This above message is for the use of the named person(s) only.

[image: vcs]

On Wed, Dec 16, 2020 at 8:53 PM Connor Shea notifications@github.com wrote:

@tegandbiscuits https://github.com/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

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rmosolgo/graphiql-rails/issues/85#issuecomment-747152340, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFKLSJLNOLFXTIOHEMKR42TSVFQARANCNFSM4N5F4BFA .

cowholio4 commented 2 years ago

@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 commented 2 years ago

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.