Manage Circular Imports Hell in GraphQL-Modules

Mar 18, 2019 · 3 min read

Designing and building modular GraphQL API may not look straight-forward the first time you start. It is hard to keep a perfect modularity with standalone and encapsulated modules.

It is really easy to appeal to the circular imports, but that’s exactly what you shouldn’t do in any case. You might say while reading this; I DON’T HAVE ANY WAY OF NOT CREATING CIRCULAR IMPORTS!

In a previous versions of GraphQL-Modules, we used to allow users to have circular imports in their GraphQL-Modules applications. However, it created a lot of extra logic which slows down the initial schema generation speed, because we always need to check if there is circular imports between modules.

Then, if GraphQL-Modules found some, it would merge all the members of this circular import into a one LARGE MODULE which was breaking almost every principle of encapsulation and modularity we mentioned in previous blog-posts of our GraphQL-Modules series.

Finally, we decided to remove this support; then force people to have strict modularity in their projects.

Forcing people out of a way of developing is always hard and we’ve got questions from you about how to solve some specific issues — so in this blog post and new doc section we will help you understand why this was a bad practice and how to migrate from it with different use cases.

The Problem

Let’s assume we have 3 different entities in our database;

Then, if we create three different modules for these three entities;

UserModule’s Schema which imports PostModule and CommentModule
PostModule’s Schema which imports UserModule and CommentModule
CommentModule’s Schema which imports UserModule and PostModule

As you can see above, every module imports other modules; and this creates a circular dependency.

You might ask if this is the only way to implement modules for these entities; because it looks like there is no point to have different modules for those schemas. Having circular dependency is the same situtation with having a single large module.

How To Solve

Let’s see what we have in terms of relationship;
- User doesn’t depend on Post and Comment
- Post doesn’t depend on Comment.

- Comment depends on User and Post, because it has userId and postId fields
- Post also depends on User because it has userId field

So let’s create modules in that way,

UserModule’s Schema
PostModule’s Schema which imports UserModule
CommentModule’s Schema which imports both UserModule and PostModule

Using this approach, you will have standalone modules; otherwise will create a big module which contains all of them like we used to handle circular deps in this way (merging all circular imports).

Also extend says that it needs a main definition from imported modules which makes the connection more readable in terms of entity relations.

The Guild

The Guild


Written by

JavaScript Enthusiast, member of The Guild

The Guild

The Guild

The Guild

More From Medium

More from The Guild

More from The Guild

More from The Guild

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade