connect
search

SDK Implementation

A useful pattern is to pack all the necessary operations of the GraphQL API into a library, referred to as an SDK in the following example. This library must implement the operations and all the necessary queries and mutations.

Example

To implement such an SDK in NodeJS:

  1. Define the queries or mutations you will make using the API. A possible implementation is:
export const TitleFragmentFragmentDoc = gql`
fragment TitleFragment on Title {
id
createdAt
updatedAt
name
slug
nodeTypeId
entityTypeId
entityTypeName
entityId
hasChildren
customFields {
...BulkCustomFieldsFragment
}
}
${BulkCustomFieldsFragmentFragmentDoc}`;
export const TitlesDocument = gql`
query titles($filters: TitleFilters, $orderBy: [TitleOrderBy!], $assocFilters: TitleAssocFilters, $first: Int, $skip: Int, $after: Cursor) {
titles(filters: $filters, orderBy: $orderBy, assocFilters: $assocFilters, first: $first, skip: $skip, after: $after) {
totalCount
pageInfo {
hasNextPage
lastCursor
}
edges {
cursor
node {
...TitleFragment
}
}
}
}
${TitleFragmentFragmentDoc}`;
export const TitleDocument = gql`
query title($id: ID!) {
title(id: $id) {
...TitleFragment
}
}
${TitleFragmentFragmentDoc}`;
export const CreateTitleDocument = gql`
mutation createTitle($input: TitleInput!) {
createTitle(input: $input) {
...TitleFragment
}
}
${TitleFragmentFragmentDoc}`;
export const UpdateTitleDocument = gql`
mutation updateTitle($id: ID!, $input: TitleInput, $unset: [String!]) {
updateTitle(id: $id, input: $input, unset: $unset) {
...TitleFragment
}
}
${TitleFragmentFragmentDoc}`;
  1. Create a layer that will make the calls of the queries or mutations. A possible implementation is:
export type Requester<C= {}> = <R, V>(doc: DocumentNode, vars?: V, options?: C) => Promise<R>
export function getSdk<C>(requester: Requester<C>) {
return {
titles(variables?: ConnectApiTitlesQueryVariables, options?: C): Promise<ConnectApiTitlesQuery> {
return requester<ConnectApiTitlesQuery, ConnectApiTitlesQueryVariables>(TitlesDocument, variables, options);
},
title(variables: ConnectApiTitleQueryVariables, options?: C): Promise<ConnectApiTitleQuery> {
return requester<ConnectApiTitleQuery, ConnectApiTitleQueryVariables>(TitleDocument, variables, options);
},
createTitle(variables: ConnectApiCreateTitleMutationVariables, options?: C): Promise<ConnectApiCreateTitleMutation> {
return requester<ConnectApiCreateTitleMutation, ConnectApiCreateTitleMutationVariables>(CreateTitleDocument, variables, options);
},
updateTitle(variables: ConnectApiUpdateTitleMutationVariables, options?: C): Promise<ConnectApiUpdateTitleMutation> {
return requester<ConnectApiUpdateTitleMutation, ConnectApiUpdateTitleMutationVariables>(UpdateTitleDocument, variables, options);
},
deleteTitle(variables: ConnectApiDeleteTitleMutationVariables, options?: C): Promise<ConnectApiDeleteTitleMutation> {
return requester<ConnectApiDeleteTitleMutation, ConnectApiDeleteTitleMutationVariables>(DeleteTitleDocument, variables, options);
}
};
}
export type Sdk = ReturnType<typeof getSdk>;
  1. Define the requester and instantiate the SDK:
async function request(query: any, variables?: any) {
const body = JSON.stringify([{
query: query.loc.source.body?.replace(/[\s,]+/g, ' ')?.trim(),
variables
}]);
const payload = {
url: endpoint,
body,
organization_slug: orgSlug,
};
const hmac = crypto.createHmac('sha256', secretKey);
hmac.write(JSON.stringify(payload));
hmac.end();
const signature = hmac.read().toString('hex');
const response = await requestretry.post({
url: `https://${endpoint}`,
headers: {
'Content-Type': 'application/json',
'X-Organization-Slug': orgSlug,
'oz-key-id': publicKey,
'oz-signature': signature,
},
body,
maxAttempts: 5,
retryStrategy: requestretry.RetryStrategies.HTTPOrNetworkError,
});
if (response.statusCode !== 200) {
throw new Error(response.body);
} else {
let gqlResponse = JSON.parse(response.body);
if (gqlResponse.length > 0) {
gqlResponse = gqlResponse[0];
} else {
throw new Error('Did not receive data from server');
}
if (gqlResponse.errors) {
throw new Error(gqlResponse.errors[0].message);
}
return gqlResponse.data;
}
}
function getConnectSdk() {
return getSdk(async <R, V>(doc: DocumentNode, vars: V): Promise<R> => {
return request(doc, vars);
});
}
const sdk = getConnectSdk();
  1. Call the SDK to make API queries and mutations to Connect:
async function getTitleById(id: string): Promise<ConnectApiTitleFragmentFragment> {
console.log('getTitleById');
const response = await sdk.title({ id });
return response.title;
}
API Based DeliveriesMarkers