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

Generated GraphQL Schema fails to be parsed due to aggregateTables empty Name fields #96

Open
metafeather opened this issue Oct 5, 2020 · 3 comments

Comments

@metafeather
Copy link

  • Are you running a release or master: master
  • Issue is about a fresh instance (no data in db) or restart: fresh

This seems a known/unfinished issue based on the commented 'Name' field in the code noted below, but I was hoping it could be addressed as it would greatly ease the discovery of the graphql endpoints generated by the db tables as they would become available in GraphiQL in #13

https://github.com/daptin/daptin/blob/bc7fcee76cb4eccc1728cf31c408d4a0c4bac9c4/server/graphql.go#L503

{
  "args": [ ... ],
  "deprecationReason": "",
  "description": "Aggregates for world",
  "isDeprecated": false,
  "name": "aggregateWorld",
  "type": {
    "kind": "LIST",
    "name": null,
    "ofType": {
    "kind": "OBJECT",
    "name": "",         <---- HERE
    "ofType": null
  }
}

Currently I am using a manual solution to enter the aggregate tables relevant list type into the introspection JSON so an SDL can be generated for Postman, e.g. aggregateWorld = world, aggregateUserOtpAccount = user_otp_account, etc

@artpar artpar self-assigned this Oct 6, 2020
@artpar artpar added this to the 1.0.0 milestone Oct 6, 2020
@artpar artpar added this to To do in Daptin core via automation Oct 6, 2020
metafeather pushed a commit to metafeather/upstream-daptin that referenced this issue Oct 6, 2020
@artpar
Copy link
Collaborator

artpar commented Oct 6, 2020

Hi @metafeather really appreciate for the pull request for fixing this.

This is a slightly more trivial issue then just setting the name there, and hence the reason why its pending.

The aggregate API is not supposed to send items which represent the original table, but instead the columns will depend on what the query was.

For example, consider a scenario where you run an aggregate over the user_account table, and try to fetch count(*) with group by on date(created_at), here you will get two columns in the response, the count and the date

{
  "count": 5,
  "date": "2020-01-01"
}

While the real user_account object defined in graphql does not have that column. So while this addition from your pull request will make that API more visible, the response object would still not show up the real fields available in response (so things like auto-complete in graphql editors won't work)

I am trying to figure a reliable and intuitive way to expose this.

@artpar
Copy link
Collaborator

artpar commented Oct 6, 2020

Btw, please do mention if you have any presupposition around using such API in graphql (where the resulting columns are based on the query itself), or if you have come across something similar in another API.

@artpar
Copy link
Collaborator

artpar commented Oct 7, 2020

https://stackoverflow.com/questions/45842544/graphql-objecttype-with-dynamic-fields-based-on-arguments

  • GraphQL is strongly typed. GraphQL.js doesn't support some kind of any field, and all types defined in your schema must have fields defined. If you look in the docs, fields is a required -- if you try to leave it out, you'll hit an error.

  • Args are used to resolve queries on a per-request basis. There's no way you can pass them back to your schema. You schema is supposed to be static.

As you suggest, it's possible to accomplish what you're trying to do by rolling your own customer Scalar. I think a simpler solution would be to just use JSON -- you can import a custom scalar for it like this one. Then just have your elements field resolve to a JSON object or array containing the dynamic fields. You could also manipulate the JSON object inside the resolver based on arguments if necessary (if you wanted to limit the fields returned to a subset as defined in the args, for example).

Word of warning: The issue with utilizing JSON, or any custom scalar that includes nested data, is that you're limiting the client's flexibility in requesting what it actually needs. It also results in less helpful errors on the client side -- I'd much rather be told that the field I requested doesn't exist or returned null when I make the request than to find out later down the line the JSON blob I got didn't include a field I expected it to.

@artpar artpar closed this as completed Feb 7, 2021
Daptin core automation moved this from To do to Done Feb 7, 2021
@artpar artpar reopened this Feb 7, 2021
Daptin core automation moved this from Done to In progress Feb 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Daptin core
  
In progress
Development

No branches or pull requests

2 participants