grin-api-sdk v1.9.1
grin-api-sdk
Grin's typescript sdk, containing apis for our services and common enums, methods and utilities.
Installing
First you need to login to npmjs registery using our rnd account.
Get the password from the password manager / somebody in the team, then run
$ npm loginand follow the steps.
After logging in, you can install the package.
Using npm:
$ npm install @grin-rnd/grin-api-sdkUsing yarn:
yarn add @grin-rnd/grin-api-sdkUsage examples
AppSync Communication
Here is a short example of how to set up an access to AppSync using the Graph module.
This example will work mostly on lambda functions, where the credentials exist on the environment variables.
Initialization
const { Graph } = require('@grin-rnd/grin-api-sdk')
const graphOperations = require('./graphql')
Graph.init('https://<UrlToYourAppsync>', {
graphOperations,
verbose: true
})Running queries and mutations
const patient1 = await Graph.api.fetchItem('getPatient', { id: 'zdibi' })
const patient2 = await Graph.api.fetchItem('patientByUsername', { username: 'zdibi' }) // fetchItem will fetch the head of the items list
const allPatients = await Graph.api.fetchAll('listPatients')
const grinDocs = await Graph.api.search('searchDoctors', {
filter: {
email: {
match: '@get-grin'
}
}
})
console.log(grinDocs) // { items, nextToken, total } or whatever is on the query
const docEmailOnly = await Graph.api.query('getDoctor', { id: 'zdibi' }, data => data.getDoctor.email)
const updatedDoctor = await Graph.api.mutateItem('updateDoctor', {
id: 'zdibi',
_version: 1
})Dynamic operations
The GraphAPI class uses gql-query-builder library to generate dynamic queries without the need to include them in the operations json passed to the GraphAPI instance.
Access the dynamic property on your GraphAPI instance to use this feature.
Example:
Graph.api.dynamic.fetchItem({
operation: 'doctorByEmail',
variables: {
email: 'ido@get-grin.com'
},
fields: [
'id',
'_version',
{
user: [ 'id', 'username' ]
},
{
patients: [
{
items: ['id']
}
]
}
]
})Check out the library's docs for more examples.
Graph Mocks
If your tests require complicated mocked Graph API responses, you can now use the Graph Mock module to simplify the process.
jest.mock('@grin-rnd/grin-api-sdk', () => ({
__esModule: true,
...jest.requireActual('@grin-rnd/grin-api-sdk'),
Graph: {
api: {
query: jest.fn().mockImplementation(
Graph.mockBuilder()
.mock('getPatient, 'testPatient2', { id: 'testPatient2', username: 'aaa' })
.mock('getPatient', { id: 'genericTestPatient' }) // Fallback for getPatient
.mock('doctorByEmail' (queryName, variables) => ({ // accepts also callbacks
items: [
doctorsByUsername[variables.username]
]
})
.getMockImplementation()
)
}
}
}))Then, when your module runs getPatient, it would get the predefined value from above:
Graph.api.fetchItem('getPatient', { id: 'testPatient2' }) // will be resolved to: { id: 'testPatient2', username: 'aaa' }The idea is that query is the base method that being invoked by all other methods such as fetchItem, fetchAll, and dynamic.
With the mock builder you define which values should be returned by query and even by specific ids.
NOTE: using this feature might change the way you mock the Graph api in general. For example, instead of replacing the entire api with a custom object, you set a spy on the methods:
beforeEach(() => {
Graph.init('https://something.test', {
graphOperations: {}
})
jest.spyOn(Graph.api.dynamic, 'mutateItem').mockImplementation((mutationName, input) => {
return Promise.resolve({ id: input?.id })
})
jest
.spyOn(Graph.api, 'query')
.mockImplementation(
Graph.mockBuilder().mock('listStatuss', { items: statusesData.statusesList }).getMockImplementation()
)
})Creating a GraphAPI instance
This is an example of how to create a GraphAPI instane, which is the class used for communication with AppSync under the hood in the Graph module.
const { GraphAPI } = require('@grin-rnd/grin-api-sdk')
const graphOperations = require('./graphql')
const graph = new GraphAPI('https://<UrlToYourAppsync>', {
graphOperations,
verbose: true
})
// now you can call the same methods as shown in the previous section, such as fetchItem, query, mutateItem and so on.LambdaAPI
This module wraps common types of lambda invocations.
It's capable of sending fake http requests to express lambad functions, or simply invoke the lambda with a payload.
NOTE: fake http requests DO NOT go through the API Gateway. It's simply invoke the lambda with an event structed as a http request.
const { LambdaAPI } = require('@grin-rnd/grin-api-sdk')
const lambda = new LambdaAPI(YOUR_FUNCTION_NAME_HERE)
// This will mock a post method: the first parameter is the endpoint path, and the second is the request body.
const postResponse = await lambda.post('/path/to/somewhere', {
hello: 'world'
})
// This will mock a get method, using the first parameter as the path. You can also add query parameters.
const getResponse = await lambda.get('/path/to/somewhere?hello=world')
// You can also create your own http request if the existing methods do not suite your needs:
const response = await lambda.mockHttpRequest(
'PATCH',
'/path/to/somewhere',
{ 'hello': 'world' }, // body
{ 'content-type': 'application/json' } // headers
)
// This will invoke the lambda. The object argument will be passed as the event.
const invokeResponse = await lambda.invoke({ hello: 'world' })GrinAxios
This is just a wrapper for axios package that implements retries mechanism using exponential backoff.
Just import GrinAxios and use it as a regular axios package:
const { GrinAxios } = require('@grin-rnd/grin-api-sdk')
const res = await GrinAxios({
method, // GET, POST, PUT, DELETE, ...
url,
data: req.body,
headers: req.headers
})LambdaUtils
recordParser
Use recordParser to parse a lambda trigger DyanmoDB record to json.
const { recordParser } require('@grin-rnd/grin-api-sdk)
const record = event.Records[0]
const newImage = recordParser(record.dynamodb.NewImage)
// use newImage as a standard jsonTest with SDK Test project
- remove the
@get-grinfrom thepackage.jsonof the sdk project (just for your testing) npm run make_link- go to the grin api sdk test project -->
npm i - for every change in the sdk -->
npm run make_link--> remove node_modules in test project -->npm i