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

Part 3 - Backend #2

Merged
merged 9 commits into from Jun 1, 2018
Merged

Part 3 - Backend #2

merged 9 commits into from Jun 1, 2018

Conversation

mikestaub
Copy link
Owner

This is where all of the business logic of our app is defined, tested, and implemented.

We use yarn workspaces to split up all of the core functionality of our API into separate packages.

SOLID principles are applied as rigorously as possible. Packages are as follows:

db: this is the main class that is responsible for reading and writing data to the database. We create a GraphDatabase interface that will be consumed by the graphql package. We implement the interface with the ArangoDB driver module.

db-backup-restore: This package has two classes that will backup the entire database, or restore the database from a backup. This is done on a cron for disaster recovery. Ideally we would never need to restore the database from a backup, but we must be extra cautious.

express: This package is a standard express app, that handles authentication via passport as well as graphql requests. This package should handle all future HTTP requests to the backend API.

utils: This package is simply utilities that are needed by other backend packages.

The most important code in this PR are all the graphql integration tests. Please read them carefully. GraphQL integration tests should be considered the core value of this web application. All other packages and modules, including the React frontend, are secondary to these tests. GraphQL integrations tests define explicitly what features the web app supports. The Types ( Nodes ) are the business entities, while the queries and mutations defined the use cases those entities support.

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
Copy link
Owner Author

Choose a reason for hiding this comment

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

This self-signed cert is only used in development so it is ok to check in to git.

@@ -0,0 +1,46 @@
// @flow
Copy link
Owner Author

Choose a reason for hiding this comment

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

This file is where we define all custom flow types for our backend. Perhaps they should be defined next to their implementations, but I like the idea of having one file so it is easier to find.

@@ -0,0 +1,306 @@
/* @flow */
Copy link
Owner Author

@mikestaub mikestaub Jun 1, 2018

Choose a reason for hiding this comment

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

These types are auto-generated a package.json script! They are also used on the frontend.

@@ -0,0 +1,71 @@
import Config from "./config";
Copy link
Owner Author

@mikestaub mikestaub Jun 1, 2018

Choose a reason for hiding this comment

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

This is the entry point of our API. All needed services are instantiated here and passed as arguments to other services ( dependency injection ). Similar code must also be run in the jest tests, perhaps in the future that code can be consolidated.

@@ -0,0 +1,28 @@
// @flow
Copy link
Owner Author

Choose a reason for hiding this comment

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

These binaries are copied from the CentOS release of ArangoDB and should be updated along with the database engine.

@@ -0,0 +1,272 @@
// @flow
Copy link
Owner Author

Choose a reason for hiding this comment

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

It is a high priority to write integration tests for this module and open source it. This is critical code.

@@ -0,0 +1,90 @@
// WARNING - changing this file will mutate the structure of the database.
Copy link
Owner Author

Choose a reason for hiding this comment

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

This config allows us to declaratively define the database topology. Be careful when editing it.

@@ -0,0 +1,326 @@
// @flow
Copy link
Owner Author

Choose a reason for hiding this comment

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

This code should also be open sourced asap, as other arangodb devs might find it useful.

@@ -0,0 +1,292 @@
// @flow
Copy link
Owner Author

Choose a reason for hiding this comment

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

This code needs to be examined more closely to be sure we are not vulnerable to SQL-injection like attacks. I believe the bindVars has sanitation logic, but we are also doing some string concatenation.

@@ -0,0 +1,390 @@
<!doctype html>
Copy link
Owner Author

Choose a reason for hiding this comment

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

These email templates could be polished a bit more.

try {
return hasAuthToken(arguments[0]);
} catch (err) {
// TODO: these fields should be defined in the schema via custom directive
Copy link
Owner Author

Choose a reason for hiding this comment

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

Perhaps there is an npm module to help with this?

return { user };
}

async function update(db: Object, input: Object): Promise<User> {
Copy link
Owner Author

Choose a reason for hiding this comment

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

There are many places in the code that lazily use type Object. They should be updated to be more specific.

@@ -0,0 +1,37 @@
// @flow

// TODO: publish this as a public npm package
Copy link
Owner Author

Choose a reason for hiding this comment

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

I really like the declarative and simple style of this GraphQL authorizer module. I would love to get feedback on it from more experienced GraphQL users.

const utils = new TestSuiteUtils();
utils.setupJest();

let adminContext = null;
Copy link
Owner Author

Choose a reason for hiding this comment

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

using closure vars like this seems ugly, but I have yet to find a better way. Ideas?

@mikestaub mikestaub merged commit 6d4c2dc into master Jun 1, 2018
@mikestaub mikestaub deleted the blog-post-series/part-3 branch June 1, 2018 16:53
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.

None yet

1 participant