I recently wanted to use graphiql-rails
gem to play around with a GraphQL endpoint that I was running in a Rails project.
For some reasons, I was not able to set it up properly since the gem doesn't seem to be working without Rails Asset Pipeline... or may be I was just too lazy to look it up how to make it work.
So I came up with a workaround:
If exists, remove graphiql-rails
from Gemfile
, then run bundle
.
If exist, remove these lines from ./config/routes.rb
.
if Rails.env.development?
mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "/your/endpoint"
end
These things may have been auto-generated if you followed the installation instructions from the graphql
gem.
Add to ./config/routes.rb
get '/graphiql', to: 'graphiql#index' if Rails.env.development?
This adds a new route /graphiql
and maps it to the index
action of controller GraphiqlController
, which we are going to define next...
Create ./app/controllers/graphiql_controller.rb
with this content:
class GraphiqlController < ApplicationController
layout false
def index; end
end
We can leave the index
method empty, and continue with the view...
Create ./app/views/graphiql/index.html.erb
with this content:
<html>
<head>
<title>Simple GraphiQL</title>
<link href="https://unpkg.com/graphiql/graphiql.min.css" rel="stylesheet" />
<%= csrf_meta_tags %>
</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 graphqlEndpointUrl = "<%= graphql_url %>";
const graphQLFetcher = graphQLParams =>
fetch(graphqlEndpointUrl, {
method: 'post',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector(`meta[name="csrf-token"]`).content
},
body: JSON.stringify(graphQLParams),
})
.then(response => response.json())
.catch(() => response.text());
ReactDOM.render(
React.createElement(GraphiQL, { fetcher: graphQLFetcher }),
document.getElementById('graphiql'),
);
</script>
</body>
</html>
That content originally comes from the official GraphiQL README Page.
It loads the GraphiQL source from a CDN, so you need to be connected to the internet in order to use it.
However, the file has been enriched in 3 locations in order to work with Rails:
-
<%= csrf_meta_tags %>
: This writes the CSRF token as a<meta>
-tag, which we are going to use in the AJAX request below. -
const graphqlEndpointUrl = "<%= graphql_url %>";
: If your Rails application runs the GraphQL endpoint, its URL will automatically be defined here. -
'X-CSRF-Token': document.querySelector(`meta[name="csrf-token"]`).content
: This reads the CSRF token from the<meta>
-tag and sends it together with the GraphQL query to the Rails server. If this is missing, Rails will refuse the request with the errorActionController::InvalidAuthenticityToken
.
Finally, start the rails server bin/rails s
and go to http://localhost:3000/graphiql
:
Top comments (1)
Anyone stuck do the following:
1) Add gem 'sprockets-rails' to your Gemfile,
if you don't have it already (sporckets-rails is an asset management pipeline for rails, it provides the css and js file for the GraphiQL engine to render.)
2) create a file @ /app/assets/config/maifest.js and add the following lines
//= link graphiql/rails/application.css
//= link graphiql/rails/application.js
3) That's it,
(Mount the engine in your routes if it isn't there already.)
Follow the official solution published by graphiql-rails,
github.com/rmosolgo/graphiql-rails