-
Notifications
You must be signed in to change notification settings - Fork 95
GraphORM
GraphORM is an internal solution primarily used for translating GraphQL queries to SQL queries. With the help of TypeORM, GraphORM translates a GraphQL AST (Abstract syntax tree) into a SQL query. This SQL uses Postgres’s JSON capabilities to resolve a GraphQL query in a single SQL query that includes subqueries, joins, and everything needed to fetch the relevant information. It uses JSON to create deep hierarchy objects rather than the normalized rows of traditional SQL queries.
In this file we have our global GraphORM
instance that is used across the app. It contains the general configuration for the actual usage of the library.
interface GraphORMType
property | type | required | default | comments |
---|---|---|---|---|
from |
string |
false |
the key from the Object where this was defined |
one example is in GraphORMMapping when defining a new key with value |
fields |
An Object having keys as string and values as GraphORMField
|
false |
null |
|
requiredColumns |
string[] |
false |
null |
our GQLDatePageGenerator utilizes createdAt field for pagination, and if you happen to not need that column in your query, hence, not included in your schema, you can define that field here so the query will be able to proceed with no issue |
interface GraphORMMapping
An Object
having keys
as string
and values
as GraphORMType
.
Paginated results are very common to lessen the load requested to the server. This PageGenerator
requires two generic parameters to be passed. Though we usually utilize type inference and not explicitly define those types.
The first one is a type
that must have a property of createdAt: Date
as this will be used as a reference for the pagination.
The second one is the type
for the parameters to be passed as part of the query itself.
interface GQLDatePageGeneratorConfig
property | type | required | default | comments |
---|---|---|---|---|
maxSize |
number |
false |
100 |
max size to return per request |
interface QueryOptions
property | type | default | comments |
---|---|---|---|
queryBuilder |
(builder: GraphORMBuilder) => GraphORMBuilder |
undefined |
this is where you specify your conditions for your query, sorting, etc. |
orderByCreatedAt |
'ASC' | 'DESC' |
'ASC' |
the pagination is based on the createdAt property, hence, it depends from its actual order |
constructor
This will accept the configuration and create an instance of your page generator that can be used across the module.
Parameters
index | type | required | default |
---|---|---|---|
0 | GQLDatePageGeneratorConfig |
false |
undefined |
function queryPaginated
The method responsible for making your query paginated aligned with GraphQL's requirements
Parameters - most of the required parameters are coming from the GraphQL resolver so you won't have to think about it too much!
index | type | required | comes from the resolver? |
---|---|---|---|
0 | Context |
true |
true |
1 | GraphQLResolveInfo |
true |
true |
2 |
TArgs - the second generic type parameter mentioned in GQLDatePageGenerator 's description |
true |
false |
3 | QueryOptions |
false |
false |
import { GQLDatePageGenerator } from './pageGenerator';
// our GraphQL resolver that is uniform across the app
export const resolvers: IResolvers<any, Context> = {
Query: traceResolverObject({
samplePaginatedRequest: async (
_,
args: YourQueryArgs,
ctx,
info,
// the required type to return for a paginated query
): Promise<ConnectionRelay<YourActualType>> => {
// where the Page Generator is used
const pageGenerator = new GQLDatePageGenerator();
// as you may notice, the only thing we had to manually write is the actual query
return pageGenerator.queryPaginated(ctx, info, args, {
queryBuilder: (builder) => {
builder.queryBuilder = builder.queryBuilder.andWhere(
`${builder.alias}.postId = :postId`,
{ postId: args.id },
);
return builder;
},
orderByCreatedAt: 'DESC',
});
},
}),
};
function createPageGenerator
In the constructor
, you pass a parameter to which will become the configuration where your page generator will base off from. Whenever you want to change those settings, you can call this function which will accept the same parameters to create another Page Generator containing the new configs.
Parameters
index | type | required |
---|---|---|
0 | GQLDatePageGenerator | false |
import { GQLDatePageGenerator } from './pageGenerator';
const pageGenerator = new GQLDatePageGenerator();
// ... somewhere along the way you had to change something on some query
pageGenerator.createPageGenerator({ maxSize: 50 }); // let's say you wanted smaller size to be returned as the query is quite expensive
This library was built in-house, to provide solutions to problems encountered and make developers' experience better. It is still in its early life, so we would love it if you will be able to help us further this documentation in any way possible. If not, that's totally fine! We are already very happy to have you here!