Generate fully typed graphQL SDK with graphql-codegen
By using @graphql-codegen/typescript-graphql-request
plugin, we can generate a fully typed graphQL SDK for our graphQL queries and mutations.
We can wrap the GraphQLClient object with the auto generated getSDK
function to get a fully typed SDK for our graphQL queries and mutations.
Setup basic dependencies to enable graphQL queryable client environment
mkdir gql-codegen
cd gql-codegen
yarn init -y
yarn add graphql-request graphql
Install needed graphQL codegen plugins and config
@graphql-codegen/cli
&@graphql-codegen/typescript
: the base dependencies.@graphql-codegen/typescript-operations
: Allow sdk to operate on graphQL operations.@graphql-codegen/typescript-graphql-request
: Generate the SDK for graphQL queries and mutations.
yarn add -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-graphql-request @graphql-codegen/typescript-operations
Setup config file
import { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
overwrite: true,
documents: ["src/**/*.ts"],
schema: "https://services.dappio.xyz/graphql",
generates: {
"./src/generated.ts": {
plugins: ["typescript", "typescript-operations", "typescript-graphql-request"],
},
},
};
export default config;
Create the reference to generate SDK
graphql-codegen will generate the SDK according to the query that we define in the documents
field in the config file.
So we need to create a file that contains the query that we want to generate the SDK for.
import { gql } from "graphql-request";
export const tokenInfoQuery = gql`
query getTokenInfo($symbol: String!) {
TokenInfos(symbol: $symbol) {
timestamp
price
protocol
chainId
mint
name
decimals
symbol
logoURI
}
}
`;
And then we can run the yarn codegen
again to generate the generated.ts
file.
Use the generated SDK
import { GraphQLClient } from "graphql-request";
import { getSdk } from "./generated";
const endpoint = `https://services.dappio.xyz/graphql`;
const client = new GraphQLClient(endpoint);
const sdk = getSdk(client);
const variables = {
symbol: "ETH",
};
sdk.getTokenInfo(variables).then((data) => console.log(data));
As can be seen from the above code, we can use the generated SDK to query the graphQL endpoint with the fully typed return value.
// ...
export type GetTokenInfoQuery = {
__typename?: "Query";
TokenInfos?: Array<{
__typename?: "TokenInfo";
timestamp?: string | null;
price?: number | null;
protocol?: string | null;
chainId?: string | null;
mint?: string | null;
name?: string | null;
decimals?: number | null;
symbol?: string | null;
logoURI?: string | null;
} | null> | null;
};
// ...
Awesome! Let's try to run and see the result. Congratulations! 🎉🎉🎉🎉🎉🎉🎉🎉
Reference
If you come across the following error:
$ ts-node src/index.ts
/usr/local/lib/node_modules/ts-node/src/index.ts:744
return new TSError(diagnosticText, diagnosticCodes);
^
TSError: ⨯ Unable to compile TypeScript:
src/generated.ts:2:22 - error TS2307: Cannot find module 'graphql-request/dist/types.dom' or its corresponding type declarations.
2 import \* as Dom from 'graphql-request/dist/types.dom';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
at createTSError (/usr/local/lib/node_modules/ts-node/src/index.ts:744:12)
It's because the graphql-request
package has been updated to version 5.1.1, which has removed the dist/types.dom
file.
To fix this, we have to downgrade the graphql-request
package to version 5.1.0.
See the reference HERE
Checkout the full code here.