Optis thumbnail

Insight into our GraphQL hackathon

Once upon a time, our colleague Kenneth had an idea… an idea to try out GraphQL in a hackathon, and thus, Whats’Optis was born. Whats’Optis is the name we gave to our wannabe-WhatsApp clone. Building such an application is a great idea for learning web development, as you could add features such as authentication, file uploads, real-time messaging, making it mobile friendly and so on.

Our goal was to get to know GraphQL a bit more. Additionally, we could have some fun while working together on a project, since many of us work on separate projects for most of our time.

Getting started

One of the nice parts of GraphQL is that it requires you to create a schema, which acts as a contract between your frontend and backend so that we can develop both parts of the application at the same time. So, the first thing we did was to set up an initial version of our schema and start coding.

For our application, we decided to write the frontend with Apollo, React (including the new React hooks) and Emotion for our styled-components. On the backend, we used Apollo as well, combined with Knex.js and Bookshelf.js to communicate with our database.

Screenshot 2019 09 24 at 10 00 25

Working with Apollo

Since we were trying out GraphQL, it made a lot of sense to work with the Apollo stack. For our backend, it allowed us to easily get a GraphQL API running, by using:

const server = new ApolloServer({
  typeDefs,
  resolvers
});

server.listen().then(({url}) => {
  console.log(`🚀  Server ready at ${url}`);
});

On the frontend-part, we initially worked with Apollo Boost. Apollo Boost allows you to easily set up an Apollo client without having to worry about caching, links and so on. However, after finding out that we couldn’t customize the links that the framework would use, we decided to manually create an Apollo client.

export const client = new ApolloClient({
  resolvers,
  typeDefs,
  link: authLink.concat(httpLink),
  cache
});

To make queries with React, we first used the <Query> and <Mutation> components:

<Query query={getAuthenticationQuery}>
  {({loading, data}) => {
    {/* ... */}
  }}
</Query>

But since we were going to use React hooks everywhere else, we also tried out the new React hooks offered by the Apollo beta:

const {loading, data} = useQuery(getAuthenticationQuery);

Working with Bookshelf.js

On the backend, we used the Bookshelf.js ORM together with Knex, which abstracts database-specific stuff when querying, and allows us to easily extend our schema by using database migrations.

One of the challenges we encountered with Bookshelf.js was to reference models. We defined each model in a separate file, but importing them and using them that way didn’t yield the results we wanted. Instead of that, we had to use the Bookshelf.js registry, and reference our models using a string.

// User.js
module.exports = bookshelf.model("User", User);

// Conversation.js
const Conversation = bookshelf.Model.extend({
  uuid: true,
  tableName: "conversations",
  idAttribute: "id",
  users() {
    return this.belongsToMany(
      "User", // We could only make it work this way
    ).through(
      "UserConversation", 
      "conversationId",
      "userId");
  }
  relationships: [ "users", "messages" ]
});

The result

While we didn’t manage to finish the project, we achieved our goals, as we learned a lot of new things along the way. So, if you ever plan on organizing a hackathon yourself and you need an idea, try making a WhatsApp clone!

Our initial HTML mock is also available on Codepen, so feel free to check that out as well!

Screenshot 2019 09 24 at 15 52 59

Our passion, your dreams

Get in touch

Deze website maakt gebruik van cookies om ervoor te zorgen dat u de beste surfervaring op onze website krijgt. Meer info