Goal: perform a basic query of our database through an autogenerated GraphQL backend.
For this task we use Postgraphile, a tool modelled on Postgrest that generates an API server based on introspecting the database schema.
We will also use the Apollo GraphQL client and the vue-apollo integration.
These seem to be the most widely used libraries.
Connecting to GraphQL
In your main entry point, you can use this setup code:
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import VueApollo from 'vue-apollo';
const localApi = "/api";
const client = new ApolloClient({
link: new HttpLink({ uri: localApi }),
cache: new InMemoryCache()
});
const apolloProvider = new VueApollo({
defaultClient: client
});
Vue.use(VueApollo);
document.addEventListener("DOMContentLoaded", e => {
const vueInstance = new Vue({
render: h => h(ApplicationRoot),
provide: apolloProvider.provide()
});
vueInstance.$mount('#vue-outlet');
});
Your API will be available under the "/api" prefix to avoid CORS issues. You configure this in webpack with the following stanza:
devServer: {
port: 57242,
proxy: {
"/api": {
target: "http://localhost:5000/graphql",
pathRewrite: {"^/api": ""}
}
}
}
The Postgraphile server will appear on port 5000 by default.
Starting the server
This is extremely simple.
amoe@klauwier $ sudo yarn global add postgraphile
amoe@klauwier $ postgraphile -c postgres://localhost/mol_viewer
PostGraphile server listening on port 5000 🚀
‣ Connected to Postgres instance postgres://localhost:5432/mol_viewer
‣ Introspected Postgres schema(s) public
‣ GraphQL endpoint served at http://localhost:5000/graphql
‣ GraphiQL endpoint served at http://localhost:5000/graphiql
* * *
Your database here is mol_viewer
. A service should start on port 5000.
Writing a sample query
Using the module graphql-tag
, you can define your queries using template
literals. This will syntax-check your queries at compile time.
const demoQuery = gql`
{
allParticipants {
nodes {
reference
}
}
}`
This looks slightly weird, but the important thing to know here is that I have a
table already in my database schema called participant
. Postgraphile has
inferred a collection of objects, therefore, called allParticipants
. My table
has a field called reference
(which can be of any type). nodes
is (I believe)
a Postgraphile-specific property of the list allParticipants
. That is to say,
the text nodes
above has nothing to do with the database schema of mol_viewer
,
rather it's an artifact of using Postgraphile.
Link the query to your page
When you have set up vue-apollo
, you have access to a apollo
property on your
Vue instance. In this case it looks as such.
apollo: {
allParticipants: demoQuery
}
Here, allParticipants
is a name which must be the same as the top-level result
of the query. It's not just an arbitrary identifier.
Now, allParticipants
field exists in your component's data object. The query
is automatically made when you load your page, and allParticipants
will be
populated. You can demonstrate this through the simple addition of
{{allParticipants}}
to your template.
To iterate through the query results, you have to consider that the results of the query are always shaped like the query itself. So your basic list of the results will look as follows.
<ol>
<li v-for="node in allParticipants.nodes">
{{node.reference}}
</li>
</ol>
Filtering
Postgraphile supports filtering using the simple condition
on the
auto-generated allParticipants
field. For instance, imagine filtering by a
given reference. You'd do allParticipants(condition: {reference: "A14"})
.
Only simple equality is supported out of the box (!). Plugins are available.