Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NEW] GraphQL API #8158

Merged
merged 49 commits into from
Jan 31, 2018
Merged

[NEW] GraphQL API #8158

merged 49 commits into from
Jan 31, 2018

Conversation

kamilkisiela
Copy link
Contributor

@kamilkisiela kamilkisiela commented Sep 15, 2017

@RocketChat/core

Closes #8221

YES! YES! YES!

GraphQL is finally here!

Introduction

A couple of weeks ago we started to work on GraphQL implementation for Rocket.Chat.

For the server and also a corresponding GraphQL frontapp - Angular PWA with apollo-client and GraphQL.

To make it work on top of the existing infrastructure we had to create three packages.

I will explain each one of them separately.

We think there is a lot here that will help Meteor developers do the same transitions in their own apps.

This change will also help RocketChat scale better, making it easier for RocketChat to support different databases in the future, and to support multiple frontends and provide 3rd party API.

Let's start with something huge that has been around for quite some time and there's a lot of talking going on - GraphQL!


GraphQL

Server

The GraphQL server runs on express thanks to great apollo-server-express package.

Managing schema

Since GraphQL contains schemas and resolvers. We have to match them together somehow.

We used graphql-tools because it allows to use the GraphQL schema language to build GraphQL.js schema, and also includes useful schema tools like per-type mocking. Thanks to it, implementing new things will be super easy.

To make everything well organized we modularized schemas and resolvers with merge-graphql-schemas.

Each feature has it's own directory and contains Types, Queries, Mutations and others that belong to it separated into multiple files.

Even schemas are separated from resolvers. This way you can take a look at them conveniently and also share them easily with your dev team.

But there's more!

Subscriptions

Any messaging app needs real-time, so we also implemented GraphQL Subscriptions! The biggest feature of GraphQL since the beginning!

It allows to listen to changes of data or custom events on the receiving side of an API, such as Rocket.Chat.PWA.

Authentication

The authentication part.

We made it possible to use Rocket.Chat's and Meteor's existing accounts system in GraphQL thanks to the js-accounts stack - it's like Meteor's accounts packages but works with any server and frontend and can use GraphQL, REST or DDP under the hood.

Common logic

We managed to reuse a lot of code.

But I think the most interesting is part of a code is the one that is responsible for creating new channels.

Inside GraphQL resolver:

https://github.com/kamilkisiela/Rocket.Chat/blob/9dd51b363d68e239185f9e0b90143dc135fe0427/packages/rocketchat-graphql/server/resolvers/channels/createChannel.js#L9-L30

Inside REST API endpoint:

https://github.com/kamilkisiela/Rocket.Chat/blob/9dd51b363d68e239185f9e0b90143dc135fe0427/packages/rocketchat-api/server/v1/channels.js#L178-L204

Common logic:

https://github.com/kamilkisiela/Rocket.Chat/blob/9dd51b363d68e239185f9e0b90143dc135fe0427/packages/rocketchat-api/server/v1/channels.js#L129-L169

Both, REST API and GraphQL API share the same logic, which we think is super cool.

Used packages:


Accounts

The only purpose of this package is to integrate the js-accounts stack with MongoDB and Meteor accounts system.

What is js-accounts? A fullstack authentication and accounts-management for GraphQL and REST.

By doing this we're able to easily use current RocketChat's users ecosystem with GraphQL.

Used packages:


Grant

The main idea behind this package was to allow the external, stand-alone applications (i.e. PWA) to be able to easily use OAuth authentication that is integrated with accounts system used in Rocket.Chat.

The flow:

  1. User requests an authentication via some OAuth Provider. Let's use Google and PWA as an example.
  2. An app redirects him to a URL handled by Grant. ( http://localhost:300/_oauth_apps/connect/google/pwa).
  3. The URL is being interpreted so Grant knows which provider should be used to authenticate a user and what is the app we want to redirect him after auth completes.
  4. Authentication happens
  5. OAuth Provider sends client back to Grant, according to predefined callback url.
  6. Grant handles the response and redirects a user to the starting point with some data that allows the application to log user in.

What's the most important, every external application that has been registered in Grant ecosystem shares the same OAuth credentials for each provider.
For example, imagine we have two PWA applications, React and Angular versions. We don't need to provide two sets of credentials for Google OAuth, we only use one and flow stays the same.

Beside registering providers, Grant allows to enable and disable them whenever you want to.
Imagine a situation where Rocket.Chat, the main Meteor application exposes only Google OAuth but we already defined Facebook and GitHub in Grant. You can just turn them off.

Grant also exposes an endpoint that shows which providers are enabled and used so you can make only those visible in your application.

We also created a few packages to have something to start with:

It's super easy to add many more new providers. NPM's grant package has a lot of built-in integrations.

Used packages:


Everyone involved

I'm the author of the Pull Request but it doesn't mean I'm the only person behind it.

This is a group effort of a few friend developers who worked together:

@Urigo as a father of that project, I mean originator! and the technical leader and reviewer of both the backend and the frontend code,

@tomermoshe and @eitanfr that developed PWA and helped with the schema.

@dotansimha and @davidyaha who gave technical guidance, help and supported my issues on their core libraries.

But of course that I actually wrote the code (and the apollo-angular library)!!!

@CLAassistant
Copy link

CLAassistant commented Sep 15, 2017

CLA assistant check
All committers have signed the CLA.

@gdelavald gdelavald dismissed their stale review January 21, 2018 18:26

Working as intended, might explore this later on.

@rodrigok rodrigok modified the milestones: 0.61.0, 0.61.1 Jan 22, 2018
// the Meteor GraphQL server is an Express server
const graphQLServer = express();

if (RocketChat.settings.get('Graphql_CORS')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if this setting is changed after the server has started? Does it require a restart of the server to have an effect?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we added a middleware to check if it is enabled, this allow us to change the settings without a restart.

@rodrigok rodrigok changed the title [NEW] GraphQL [NEW] GraphQL API Jan 31, 2018
@rodrigok rodrigok merged commit 8594050 into RocketChat:develop Jan 31, 2018
@rodrigok rodrigok modified the milestones: 0.61.1, 0.62.0 Feb 14, 2018
@rodrigok rodrigok mentioned this pull request Feb 28, 2018
@bluetrade-invest
Copy link

Hey @kamilkisiela i don't can access links bellow. Can you help me? I have a lot problems with connection.

To make it work on top of the existing infrastructure we had to create three packages.

@Urigo
Copy link

Urigo commented Nov 1, 2019

I believe GraphQL has been removed from RocketChat.

We would love to help bringing it back, a lot as changed and improved since 2 years ago

@rodrigok
Copy link
Member

rodrigok commented Nov 1, 2019

Thanks, @Urigo. You are right, GraphQL was removed, we are focusing right now to move everything possible to our REST API and then we will reevaluate the possibility to start a GraphQL API.

It would be awesome to receive contributions on a new spec for the new implementation and on toolings to test load and performance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GraphQL Support
9 participants