Based on React apollo starter kit
Fork this boilerplate code to get started with GraphQL, and Apollo with Scaphold.io
Quickstart:
-
Go to Scaphold.io
-
Create an account and dataset.
-
Change the URL in the API manager (config.js) in the boilerplate to point to your unique Scaphold.io API URL.
-
Install dependencies:
npm install
-
Run with:
npm start
Open browser at: localhost:3001
Please open the browser console and monitor the logging there to see what goes on under the covers...
It should open the login screen. Try entering some login credentials and it should respond with:
{ "graphQLErrors": [ { "message": "Could not find a user with that username", "locations": [ { "line": 2, "column": 3 } ], "path": [ "loginUser" ], "name": "GraphQLError" } ], "message": "GraphQL error: Could not find a user with that username" }
Showing that it really works!
Now go to the register tab and register with a username and password. Then go back to login tab and login with those credentials and it should display Login successful :)
It really works! :D
Deployment:
Note: For development, you only need to run npm start
-
Run
npm run build
to transpile ES6 code from the src/ directory to JavaScript in the lib/ directory. -
Set the environment variable
process.env.NODE_ENV = 'production'
to let server.js know to run the code in the lib/ directory.
scaphold.io
The main points of interest are the vue-apollo
integrations and GraphQL queries.
Vue 2
vue-material
vue-router
GraphQL
Apollo GraphQL client
- put GraphQL data in your UI
- Apollo mutate API
- Apollo observable query
- vue-apollo mutations
- graphql subscriptions
- introducing vue apollo blog post
Extra tools
The vue-apollo
author recommends defining the apollo queries directly on the component using the special apollo
key:
// Apollo GraphQL
apollo: {
// Local state 'posts' data will be updated
// by the GraphQL query result
posts: {
// GraphQL query
query: postsQuery,
// Will update the 'loading' attribute
// +1 when a new query is loading
// -1 when a query is completed
loadingKey: 'loading',
},
},
Here is a good mutation example:
export default {
// Attribute
props: {
// Post id passed down to this component
postId: {
type: Number,
required: true,
},
},
methods: {
upvote() {
// Mutation
this.$apollo.mutate({
mutation: upvoteMutation,
variables: {
postId: this.postId,
},
}).then(data => {
console.log('Done upvoting.');
});
},
},
};
Please refactor the current Vue2 components to follow best practices!
Also have a look at: vue-apollo: hello world example
There is now a vue-supply module which makes it easier to supply Vuex with external data, such as via Apollo.
"Efficiently managing reactive and living data from an external source can become difficult in a large app or when using vuex. With vue-supply, you can easily consume data and automatically activate or deactivate subscriptions."
All the GraphQL queries can be found in queries.js
under src/vue/components/App
The mutation queries can be found in mutations.js
which use the GraphQL mutation queries defined in queries.js
.
createUser
LoginWithData
LoginWithData
Takes an object with username
and password
, then attempts to login via GraphQL API on scaphold.io.
createUser
Creates a new user (ie. Registration). We can then use this user account to login.
Takes an object with username
and password
Folder: src/vue/components/App
In App.vue
we have a method createUser()
which I'm not sure how it fits in... but this is the method used to make a
mutation on the GraphQL backend at scaphold.io to actually create a User
object in the data store RethinkDB.
methods: {
createUser() {
this.$apollo.mutate(mutations.createUser({
username: this.username,
password: this.password
}))
subscribe to user
There is also a subscribeToUser
method used to subscribe to new users (via RethinkDB changefeed)
"RethinkDB pushes JSON to your apps in realtime."
Currently it polls every 30 seconds (ie. every minute: pollInterval: 60000
ms)
subscribeToUser(id) {
const observable = this.$apollo.watchQuery({
query: userQuery,
fragments: createFragment(FragmentDoc),
pollInterval: 30000,
forceFetch: true,
variables: {
id,
},
})
const subscription = observable.subscribe({
next(result) {
// error handling
...
// save in local storage
// update component state
}
})
}
You need to first register in order to login!
Contains the following data, bound to the form dialog.
{
showModal: false, // show modal or not
registerEmail: undefined, // user email
registerPassword: undefined, // user password
errors: undefined // registration error
}
Contains an apollo mutation method to perform a loginWithData
methods: {
login(ctx) {
return this.$apollo.mutate(LoginQuery)
},
...
}
The method loginUser
executes login
, passing username
and password
.
On login success (ie. no errors
in returned data
), it stores token
and id
in localStorage
then redirects to home
.
loginUser() {
this.login({
username: this.email,
password: this.password
}).then(({ data }) => {
if (!data.errors) {
localStorage.setItem('token', data.loginUser.token);
localStorage.setItem('userId', data.loginUser.id);
// ...
MIT For you pleasure ;)