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

GraphQL syntax for simple join? #220

Closed
capouch opened this issue Nov 9, 2016 · 8 comments
Closed

GraphQL syntax for simple join? #220

capouch opened this issue Nov 9, 2016 · 8 comments

Comments

@capouch
Copy link

capouch commented Nov 9, 2016

I am very new to GraphQL/Relay and if these questions aren't appropriate as issues just let me know and I'll find another venue.

I've already figured out how to do this when I can write my own GraphQL schema; the automatic mapping from the relational tables is still a mystery to me.

How could I do something like this simple join in the Postgraphql environment:

select first_name, last_name from forum_example.person as person, forum_example.post as post where person.id = author_Id and post.id = 1;

@calebmer
Copy link
Collaborator

calebmer commented Nov 9, 2016

{
  postById(id: 1) {
    personByAuthorId {
      firstName
      lastName
    }
  }
}

I'm hoping to add some example queries to the docs soon, hope this helps 😊

@capouch
Copy link
Author

capouch commented Nov 10, 2016

Indeed that query was just what I was hoping to see, thank you very much. I'm an old Postgres hand, but very new to GraphQL.

@capouch capouch closed this as completed Nov 10, 2016
@capouch capouch reopened this Nov 10, 2016
@capouch
Copy link
Author

capouch commented Nov 10, 2016

@calebmer Sorry I re-opened this. The query works perfectly, but where did personByAuthorId () come from? I see referenced in ~src/postgraphql/__tests__/__snapshots__/postgraphqlIntegrationSchema-test.js.snap, and in other apparent snapshot files in the tests dir. But I can't figure out where it is defined.

If it is auto-generated by Postgraphql, then the question becomes, "How does one discover the full set of such queries/mutations available?" Thanks, hope I'm not being a PIA.

@calebmer
Copy link
Collaborator

Yep, PostGraphQL generates it all, but you can find all the documentation in GraphiQL. By default when you start PostGraphQL you can find GraphiQL at http://localhost:5000/graphiql 👍

Start typing a query and hit shift+space to see autocomplete options (like the dropdown in the picture below). In the top right corner there is also a “Docs” button which you can click to open up the documentation explorer which will allow you to browse the entire schema. Picture attached below:

screen shot 2016-11-12 at 10 28 44 am

@capouch
Copy link
Author

capouch commented Nov 12, 2016

I've been using GraphQL for almost a year. I'm not an advanced user but "familiar."

I'm stuck on how some of the things happen internally, and personByAuthorId is a perfect example. I want to understand how it, and its attendant comment, got auto-generated by Postgraphql. In other words, how would I know when looking at the forum_example table structure that a result of that design would be that particular query, and that particular comment "Reads a single Person that is related to this Post." That wasn't a comment anyone entered during the tutorial and it's not in a database dump of the project schema. How did Postgresql know how to generate it?

I'm trying full-time ATM trying to understand everything, but I get hung up on things like this in my discovery, and the central question, "How do you set up your tables to auto-generate the GraphQL part, and how do you know the identifiers of the generated GraphQL?" personByAuthorId is a wonderful example of a big sticking point in my efforts.

Is there a Slack channel or IRC room for the project? I know it's a burden on your development time to have to stop to answer newbie questions.

Sorry for the bother.

@calebmer
Copy link
Collaborator

Gotcha, wasn’t sure what exact level of the stack you were looking for 😉. There is a chat channel on Gitter for this project: https://gitter.im/calebmer/postgraphql

Now that I understand what you are actually trying to ask, I’ll go a bit more in depth because this is actually a fun question to answer 😊

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

@capouch capouch closed this as completed Nov 14, 2016
@capouch
Copy link
Author

capouch commented Nov 14, 2016

Thanks SO MUCH for the detailed explanation, which is indeed just what I was looking for. I'll for sure e out of your hair for a while as work through all of this. I did understand earlier about the desire to have a generic "abstraction matchup" platform. I'm not a big enough boy yet to fully absorb the details, but I'm working on it as hard as I can. Thanks again.

@benjie
Copy link
Member

benjie commented Nov 15, 2016

This is super informative; I've created a wiki page for this answer: https://github.com/calebmer/postgraphql/wiki/Code:-how-are-things-like-barByFooId-built%3F

I think after a small amount of editing we should consider adding links out to stuff like this from https://github.com/calebmer/postgraphql/blob/master/src/README.md

Nice one Caleb! 👏

benjie added a commit that referenced this issue Jan 27, 2020
* Reproduce issue

* Fix issue

* Fix handling of null entries

* Handle complex nulls via __isNull

* Add some comments
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

No branches or pull requests

3 participants