Blog

GENERATING TYPE-DEFS FOR ENTERPRISE FEDERATED GRAPHQL: THE WEBILL WAY

type-defs
WeBill

GENERATING TYPE-DEFS FOR ENTERPRISE FEDERATED GRAPHQL: THE WEBILL WAY

PART 1: THE PROBLEM STATEMENT AND THE END SOLUTION

The entire WeBill development ethos is underwritten by the guiding principle that all of our developers must adhere to the WeBill design and methodology. When we carry out code reviews all the code developed by Tim must be indistinguishable in style and form from the code developed by myself or Jedd. In an enterprise scale development of the magnitude of WeBill single-man dependency and individual idiosyncrasies are anathema. New developer recruits are taught the methodology, design and style, and, within a month or two, can swim in the code developed months ago by developers who have long departed from the company. Sustainability of code is crucial and methodology is key. What I mean by “methodology” is difficult to articulate but it includes design, style, template and convention. We strive to be at the cutting edge of technology, and, at times, templating and convention can dumb down complexity, but it works for us. We have a factory-line development process which we believe deals with cutting edge technology and issues. Learn the method and the complexities of all new technology we adopt becomes trite.

Recently we decided to move our entire enterprise to the newly released Apollo GraphQL Federation. GraphQL Federation was the answer to the micro-service conundrum and multiple product nature of our business. We have a number of products which share types amongst themselves. Each product was supposed to be a discrete, independent micro-service environment of its own. Unfortunately, on the graphql level because types and constructs were shared, we had to break the Chinese walls we wanted to set up between each product. We could not get “stitching” to work for us. GraphQL federation was the answer.

The problem was getting GraphQL Federation on enterprise scale to work in our factory-line approach. This problem was exacerbated by our insistence on the WeBill “methodology”. The GraphQL Federation documentation was adequate but, as with all documentation and tutorials, did not give an answer to our enterprise concerns. In this series of articles I will walk through our methodology.

The following are the series of articles I plan to write on this topic:

1. Describe the problem and show the end result

2. Explain the user of functional programming and deployment of the ramda library to create the magic

3. Code walk-through of the utility library responsible for the solution

A: THE PROBLEM

At WeBill we have a number of inter-linked products. Field Manager is a web and mobile product for utility field workers who read meters, install meters, disconnect and connect meters and perform other field work on utility assets. Facility is a web and mobile product for facility managers to manage utilities in facilities such as shopping malls, office blocks, hotels, residential complexes and so on. A WeBill User can sign on and use both Field Manager and Facility products. The same User credentials are valid in both products. User management is handled in the Org product which deals inter alia with UsersRoles and Security.

All the above products, Field ManagerFacility and Org (there are many more) have their own data-bases, graphql servers and AWS assets such as dynamo-db, step functions and lambdas. These artefacts are not shared between products. Within each product there are a number of modules. Facility for example has over 20 modules such as TeamInstructionContractor and Device. Each Facility module has its own graphql types, inputs, queries, mutations and subscriptions. The Facility graphql artefacts are hosted in the Facility GraphQL Federated Service. We use a mono-repo and each product is a project within a lerna mono-repo. (I will impress upon our devops manager, Jedd, to write a series of articles on how we set up lerna).

Essentially a single project in most cases maps to a product. Each product project has the following packages:

  • common — code shared by all the packages in the project
  • gql — graphql definitions, resolvers and the Graphql Federated Server.
  • lib — the domain logic
  • sls — AWS lambda and step functions and other AWS code
  • test — comprehensive unit tests for sls and lib.
Sample WeBill package project

This series of articles is going to focus on the gql package of the product project. As dictated by Apollo Federation, there is a separate project called gateway which federates all of the individual project GraphQL federated services.

Because there are so many modules in Facility, each module graphql types need to be defined in separate folders. If we wrote all of Facility graphql definitions on a single file, the file would be thousands of lines. Not only is it unwieldy and well-nigh impossible to work on such a massive graphql definition file, a single file also rules out more than one developer working on the graphql definitions at the same time. Recall Facility has a number of modules and more than one developer is working on a different module of Facility at any given time. Moreover, the tooling and linting for graphql is not all-together there yet, so when defining types at scale, it can take days to find the errant “:” in a single definition on the massive single file that is preventing your graphql types from being successfully parsed.

We therefore had no choice but to define the graphql types for each module within the Facility project separately from the other modules. In fact we took it to the extreme. Each module had to have its own file for graphql schema, inputs, query, mutation and subscriptions.

Each module has its own resolver. This series of article however will not cover with how we deal with resolvers.

Before federation, we managed to modularize our disparate graphql definition files more or less following the method described in the official Apollo GraphqlServer documentation for modularising resolvers with lodash’s merge.

The structure of a module before federation was as follows:

Previous gql project structure

Leave your thought here

Your email address will not be published. Required fields are marked *