Node.js clients for querying the the FT Core Subscription and AIM GraphQL API's, along with type definitions.
Install the dependency to your project
$ npm install --save @financial-times/node-subs-and-aim-clients
Using the clients within your project
const subsGraphqlClient = require('@financial-times/node-subs-and-aim-clients/subs').default;
const aimGraphqlClient = require('@financial-times/node-subs-and-aim-clients/aim').default;
// or
import subsGraphqlClient from '@financial-times/node-subs-and-aim-clients/subs';
import aimGraphqlClient from '@financial-times/node-subs-and-aim-clients/aim';
const subscriptionClient = subsGraphqlClient({
systemCode: 'example-system-code',
apiKey: 'your subscription GraphQL API key'
});
const accessClient = aimGraphqlClient({
systemCode: 'example-system-code',
apiKey: 'your access GraphQL API key'
});
subscriptionClient.QUERY_NAME(QUERY_VARIABLES);
accessClient.QUERY_NAME(QUERY_VARIABLES);
Name | Type | Required | Description |
---|---|---|---|
system-code |
string | Yes | The system code for the consuming app |
apiKey |
string | Yes | Your API key for the relevant GraphQL API |
useTestEnvironment |
boolean | No (default = false) | A switch for using the test GraphQL env |
fetch |
Fetch | No (default = false) | A fetch instance to be used by the GraphQL Request library |
Note: When setting the useTestEnvironment
option to true the apiKey
option will also need to be set to a test key.
Note: If the consuming application has a global fetch instance that has additional features such as request tracking & metrics then you will likely want to use the fetch
option.
Queries defined within the queries
directory are then available as methods on the clients.
Each query method is a function that will return a Promise
.
Should the query need variables these can be passed into the function as arguments.
The below example illustrates how this would look for a query called getUserSubscriptions
which requires the users uuid as a variable/argument.
const userSubscriptions = await subscriptionClient.getUserSubscriptions({
uuid: '00000000-0000-0000-0000-000000000000'
});
Install dependencies
$ npm install
In order to work on this package locally you will need to link it to a consuming application.
Within your local package directory you will first need to build the package. This will produce the generated Codegen code and transpile any TypeScript into JavaScript.
$ npm run build
Note: After making any changes to the package its likely you will need to rerun the build script
Next you will need to link the package to your application. We recommend that this is done via a relative dependency within your package.json.
"@financial-times/node-subs-and-aim-clients": "../path_to_your_package_directory"
Then you can run $ npm install
within your consuming application directory.
Now you should be able to use the package as outlined in Using the client.
Each client (subs & aim) has its own directory within the queries
directory where its queries are stored.
Any queries within a .graphql
file, including within nested directories will be consumed by the client.
The name used in your query will be exposed as the method on the relevant client.
When naming your queries please consider that
- Every query name must be unique
- Verbose and descriptive names are preferred
a. eg.
UserTransitionOffers
is preferred overUserOffers
- Whilst system specific queries should be rare, if you need to add one make it clear in the query name
a. eg.
${systemCode}UserData
Example query
query OfferById($id: String!) {
}
Example query use
const offerData = await subsClient.OfferById({
id: 'example-id'
});
There are some rare cases where we want to try and make it clear that a query should only be used by a single consuming application. In these cases we have stored the queries within a directory named after the system code of that application.
Example /queries/subs/next-profile/*.graphql
An example of why we are doing this is the large user data queries used in next-profile and next-retention.
We would like to revisit these queries and reduce the fields we are querying for to better understand what data each system is using. Storing them separately allows us to alter the queries without needing to test them in all applications.
If you are making a change that removes fields from a query or deleting a full query then this must be released as a new major/breaking change to avoid breaking consumers.
As these clients are reliant on API's and their schema's that are outside of this teams control, we have put in place some checks to keep us informed should there be a breaking change.
Once a day we will run a nightly CircleCI workflow. As part of the build
step in this workflow we run a task to diff the local (stored in github) schema against the remote (production) schema.
If the remote schema contains breaking changes against the local schema then the build will fail and a slack alert will be sent to the Retention team channel.
When rebuilding the clients locally the build step will fail if a query contains a field that is no longer available from the remote schema.
Its important that whenever we come across a breaking schema change that we discuss that change with either the Subs and Payments team or the Access and Identity team.
If the change is intentional then we will need to update the affected queries and release a new version of the clients as a Major/Breaking change. Each affected application will then also need updating to the latest client version.
Please isolate the schema changes into their own PR so that they could easily be rolled back if needed. Example PR here.