Hasura vs Apollo Server vs Prisma 2

Introduction

A question we've commonly been asked is how "Hasura compares to Prisma 2", or "How Hasura compares to Apollo (Server)".

To answer this question, the ideal scenario is probably to discuss:

  • The functionality each of the tools provides
  • Where each piece typically lives in an application, and their relationships to each other

Hasura

Hasura is a web service that connects to one or more data sources, and exposes a GraphQL (and optionally, REST) API for the data source.

It allows you to federate/compose/stitch other REST or GraphQL API's into this data-source graph, to create a unified data-access hub.

A configurable authorization layer allows you to set up permissions for access to both datasources (at the schema/table/column/row levels) and REST/GraphQL API endpoints or resolvers that you've pulled into Hasura.

Apollo Server

Apollo Server is a GraphQL server framework for Node.js. It allows you to write your own GraphQL server implementation.

Let's look at the example provided from the Apollo Server docs:

Below, we create a GraphQL server that has one query, called books, which returns a mocked, static array of book objects.

Typically besides boilerplate CRUD operations on database objects, you also have resolvers that do things like:

  • Process a payment with Stripe/Braintree
  • Send a welcome email to users when they sign up
  • Perform authentication by comparing a form-filled password against the securely-hashed password stored in the DB, then signing a JWT token if they match
  • Etc. <!--kg-card-end: markdown-->
const { ApolloServer, gql } = require('apollo-server');

// A schema is a collection of type definitions (hence "typeDefs")
// that together define the "shape" of queries that are executed against your data.
const typeDefs = gql`
  # This "Book" type defines the queryable fields for every book in our data source.
  type Book {
    title: String
    author: String
  }
  # The "Query" type is special: it lists all of the available queries that
  # clients can execute, along with the return type for each. In this
  # case, the "books" query returns an array of zero or more Books (defined above).
  type Query {
    books: [Book]
  }
`;

const sampleBooks = [
  {
    title: 'The Awakening',
    author: 'Kate Chopin',
  },
  {
    title: 'City of Glass',
    author: 'Paul Auster',
  },
];

// Resolvers define the technique for fetching the types defined in the
// schema. This resolver retrieves books from the "books" array above.
const resolvers = {
  Query: {
    books: () => {
      return sampleBooks
    },
  },
};

const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

Prisma

Prisma 2 is a library that provides you access to your database when writing Node.js code. It falls into the category of "ORM" tools, similar to ActiveRecord, EntityFramework, TypeORM, SQLAlchemy, or others you may be familiar with.

It connects to a data source, and gives you the ability to write code that can query the data source -- this code lives inside of your business logic (API endpoints, internal scripts/tooling, wherever).

What does this mean?

As you may have concluded at this point, these tools aren't so much alternatives to each other, as they are _ orthogonal libraries solving different sets of problems _.

When building applications, you almost always need some sort of custom business logic for handling particular tasks.

Hasura can't write this code for you (it may be a bit magical, but not it's not that magical!). What this means is that you're likely going to have to write this custom code, and ultimately need a way of integrating it with Hasura.

One of the ways you could integrate your custom business logic with Hasura is through the use of a Remote Schema, which forwarded requests to Apollo Server and called your resolver functions there.

Or perhaps you have an Express.js API with Prisma already integrated into it, accessing data as part of carrying out your business logic.

Attaching that REST API endpoint to Hasura, using Actions would be a way of integrating both Express and Prisma into your Hasura stack.

Conclusion

We hope that this post has given you a better understanding of all technologies discussed, and that the concrete examples were useful in demonstrating how these tools can be complementary if needed.

24