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

feat(icy-graphql-client): adds base skeleton of icy-graphql-client library [sc-39773] #6

Merged
merged 17 commits into from
Sep 21, 2022

Conversation

AlejandroFabianCampos
Copy link
Contributor

@AlejandroFabianCampos AlejandroFabianCampos commented Aug 30, 2022

Summary

Adds icy-graphql-client library to interface with developers.icy.tools

image

image

image

TODO

  • library documentation

@AlejandroFabianCampos AlejandroFabianCampos self-assigned this Aug 30, 2022
@shortcut-integration
Copy link

This pull request has been linked to Shortcut Story #39773: Add one RPC function migration to SDK.

@AlejandroFabianCampos AlejandroFabianCampos force-pushed the feat/sc-39773-add-graphql-client branch 2 times, most recently from be22ce6 to 895b7ee Compare September 6, 2022 23:54
@AlejandroFabianCampos AlejandroFabianCampos marked this pull request as ready for review September 9, 2022 18:34
Copy link
Contributor

@jkolyer jkolyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you include a command line shortcut for running tests plz?

I'm going to refactor the package.json scripts after I clean up the qn-ts scripts.

tools/scripts/publish.mjs Show resolved Hide resolved
@jkolyer jkolyer self-requested a review September 12, 2022 16:25
Copy link
Contributor

@jkolyer jkolyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

My suggestion is we flag all known refactoring opportunities and do them in another iteration.

@AlejandroFabianCampos AlejandroFabianCampos force-pushed the feat/sc-39773-add-graphql-client branch 2 times, most recently from 821c291 to f7d276b Compare September 14, 2022 21:11
@@ -0,0 +1,18 @@
{
"extends": ["../../../../.eslintrc.json"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we not just have these configs shared the root monorepo level?

Copy link
Contributor Author

@AlejandroFabianCampos AlejandroFabianCampos Sep 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably yes, would need to test to double check, though I think it'd be fair to keep these in case any project needs to have any specifics (i.e. react hook linting or w.e.), they are automatically generated by nx to begin with so no effort is really being had for them to be created to begin with. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh I actually just learnt that specifically for eslint config, trying to override turn off the @typescript-eslint/ban-ts-comment rule that because of NX's base override of eslint, you need to override per project these rules or do more extensive eslint setup 🤦
nrwl/nx#5866

}

const ICY_GRAPHQL_CLIENT_SUPPRESS_WARNINGS =
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably just worth getting rid of this ESLINT rule if we're going to do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I think that's fair, will add todo comment to keep track

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied on 084d13a!

const result = await this.apolloClient.query(options);

if (result?.data && typeof result?.data === 'object') {
result.data = removeNodesAndEdges(result.data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can do this in an ApolloLink and not have to have this icyGraphQLClient. Basically as middleware and apply to all responses

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I had the same thought going off of https://www.apollographql.com/docs/react/networking/advanced-http-networking/#modifying-response-data, but it seems like Apollo's in memory cache is run in between links (didn't get to dive fully on this, so might be slightly wrong on relation of errors) doesn't love that the actual structure and not just the scalar properties are modified apollographql/apollo-client#8677, so was getting errors left and right.
On a side learning, I also intended on directly extending Apollo's client and overriding the query method calling super and then modifying on the last mile, but it was causing typing issues as I learnt that you can't actually override the function signature (i.e. returning flattened data type) from the parent class; that's the reason for the total custom client that in itself delegates to the apollo client

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm this makes sense, I briefly looked into it and yeah it seems like you might get some issues modifying the schema like this. So I think this is probably the correct layer to do it. In the past we've made our own useQuery hook so you don't have to declare a custom client, but obviously it's necessary for this.

Should we make the standard apollo client private in IcyGraphQLSDK? And I wouldn't be opposed to calling the icy client client and the apollo one baseClient or something if we want to ensure the "icy" one is used always instead of the base apollo one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make the standard apollo client private in IcyGraphQLSDK?

This is something I actually gave some thought, my feeling was that it could be helpful to expose the apollo client we build so that we can in the future instruct users to access that apollo client if they want specific data (and hence save them the hassle of setting up the http/error/auth links if they just want to get bootstrapped fast)
On second thought though, we could make it private as a property and set a custom named getter method if you think that'd be more clear? My logic on naming was a direct consequence of assuming that we'd be exposing both the "apollo" raw client and the "icy" higher level client

Note of color as well though, I was thinking that on our "Icy" higher level client we will probably not be 1:1 matching functionality the same as Apollo client, i.e. one improvement I was thinking along this line (longer term) is that we could return a "IcyResponse" instance as a superset of ApolloResponse with flattened data and magic pagination methods (i.e. response.nextPage())

Copy link
Contributor

@danieljvdm danieljvdm Sep 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my feeling was that it could be helpful to expose the apollo client

I meant make the standard client private, not the icy one.

When do you think users will need to use both clients? The icy one should just be a "superset" of the apollo one, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When do you think users will need to use both clients?

i.e. when a user wants to fetch some specific data or filter that is not fully covered by our abstraction SDK, they can access our raw apollo client and forward the sql query without having to do the auth/http/error link setup themselves

The icy one should just be a "superset" of the apollo one, no?

Technically no, because of not directly extending the apollo client as a consequence of method signatures being modified, but also it might be an opportunity to bring a more "graphql for dummies" sort of ORM approach

Note of color as well though, I was thinking that on our "Icy" higher level client we will probably not be 1:1 matching functionality the same as Apollo client, i.e. one improvement I was thinking along this line (longer term) is that we could return a "IcyResponse" instance as a superset of ApolloResponse with flattened data and magic pagination methods (i.e. response.nextPage())

@@ -0,0 +1,38 @@
import { gql } from '@apollo/client/core';
import { PaginationArgs } from '../../../types';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would prefer an absolute path here ... from '~/types' or whatever the path is

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had tried using basePath alias imports like 830fefe#diff-84aee5d7a1e271d85603f9d48b0100bd95edc3757d17a330eb5475dd8c99abe2L6 but it was causing issues when the code was directly reimported on other nx projects like on https://github.com/quiknode-labs/qn-oss/pull/6/files#diff-9d88951a6aa436ee6e66eb18c9215ab66c0f29e9cb8d6d5d674b668c2ddbc61aR1, it might be possible to fix with specific aliases or some top level ts config, but I was planning on punting this as an improvement for now, WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Punting is fine, but would like to be able to use absolute paths at some point here

/**
* @todo implement generic typing
*/
export const removeNodesAndEdges = (data: any): any | any[] => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have fun typing this hehe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah haha, we'll have to get back to it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's probably not really that necessary since i don't think you can ever use the output of this method in a context that retains types

@AlejandroFabianCampos AlejandroFabianCampos force-pushed the feat/sc-39773-add-graphql-client branch from 6ddac45 to 084d13a Compare September 15, 2022 17:22
…ests be consistently replayable from recordings
…ed response data flatenning for abstraction purposes
@AlejandroFabianCampos AlejandroFabianCampos force-pushed the feat/sc-39773-add-graphql-client branch from 084d13a to 4e80320 Compare September 19, 2022 13:38
@AlejandroFabianCampos AlejandroFabianCampos force-pushed the feat/sc-39773-add-graphql-client branch from 06e74b0 to 7fbaeb2 Compare September 20, 2022 15:18
… renames CustomGraphqlClient -> CustomApolloClient
@AlejandroFabianCampos AlejandroFabianCampos merged commit 67ce48e into main Sep 21, 2022
@AlejandroFabianCampos AlejandroFabianCampos deleted the feat/sc-39773-add-graphql-client branch September 21, 2022 14:48
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

Successfully merging this pull request may close these issues.

3 participants