Skip to content

Code: how are things like barByFooId built?

Benjie Gillam edited this page Dec 15, 2016 · 2 revisions

The GraphQL interface is generated from a core set of interface files which can be found in the src/interface directory. These interface files are designed to be more opinionated then the simple GraphQL type system, allowing the interface to be turned into virtually any API frontend (REST, SOAP, GraphQL, Falcor, gRPC) powered by any API backend (PostgreSQL, MySQL, MongoDB, etc.). Some of the more important interfaces include Collection, CollectionKey, and Relation. Collection is analogous to a table in SQL, a collection in NoSQL, or a label in a Graph database. It can represent any large set of values with the same type which may not necessarily have a fixed count. CollectionKey represents the way for a user to select a single value from a Collection, and Relation represents a unidirectional relationship (tail -> head) between the values of two Collections. This interface is not perfect and needs some work, but the goal is for PostGraphQL to eventually become a data platform that extends beyond basic Postgres -> GraphQL.

These interface objects are generated by the modules found in src/postgres. Specifically of interest to you will probably be src/postgres/introspection and its utility file postgraphql/resources/introspection-query.sql. We run that introspection query and get a bunch of objects from Postgres’s system catalog schema (pg_catalog). Including objects from pg_catalog.pg_namespace (schemas), pg_catalog.pg_class (tables and composite types), pg_catalog.pg_attribute (columns for pg_catalog.pg_class), pg_catalog.pg_type (types), pg_catalog.pg_constraint (constraints like foreign key constraints, primary key constraints, and unique constraints. we use this to generate CollectionKeys and Relations), and pg_catalog.pg_procedure (Postgres functions). The TypeScript types for our introspection can be found in src/postgres/introspection/object. We turn these introspection objects into our internal interface objects in the function: addPgCatalogToInventory.

Our abstract inventory interface (which now has a Postgres implementation) is then consumed by functions in src/graphql such as getCollectionGqlType.

If you specifically want to see the flow of generating the personByAuthorId field, here is the code path:

  1. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/resources/introspection-query.sql#L207-L235
  2. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/src/postgres/introspection/object/PgCatalogConstraint.ts#L16-L26
  3. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/src/postgres/inventory/addPgCatalogToInventory.ts#L42-L75
  4. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/src/interface/collection/Relation.ts
  5. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/src/graphql/schema/collection/getCollectionGqlType.ts#L86-L87
  6. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/src/graphql/schema/collection/createCollectionRelationTailGqlFieldEntries.ts#L39-L61
  7. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/src/graphql/schema/collection/createCollectionRelationTailGqlFieldEntries.ts#L52-L53
  8. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/src/postgres/inventory/collection/PgRelation.ts#L27-L36
  9. https://github.com/calebmer/postgraphql/blob/e933d584ab4566dffe5731ce9bfbd1221b77a4cc/src/postgres/inventory/collection/PgCollectionKey.ts#L94-L182

(Taken from https://github.com/calebmer/postgraphql/issues/220)

Related, another bit of elucidation: https://github.com/calebmer/postgraphql/issues/265#issuecomment-265736977