-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dataloader): create an example app that uses Apollo, koa, a data…
…loader, and Mongo or DynamoDB Except for the dataloader, these are all things we instrument, so we should be seeing spans for all of them once our instrumentation is working. And as far as I can tell... we do.
- Loading branch information
Jordi Gutiérrez Hermoso
committed
May 18, 2023
1 parent
612efdd
commit 6a09089
Showing
17 changed files
with
5,410 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
FROM node:lts-slim | ||
EXPOSE 4000 | ||
|
||
RUN apt-get update && apt-get install httpie jq -y | ||
|
||
WORKDIR /app | ||
COPY app . | ||
COPY entrypoint.sh /entrypoint.sh | ||
RUN npm ci | ||
|
||
ENTRYPOINT ["/entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
This is an example of an Apollo server using the Koa middleware and dataloader | ||
|
||
Get it running: | ||
|
||
1. Copy sample.env to .env | ||
2. Edit .env to add your New Relic ingest key, and any other desired changes. | ||
3. Start with `docker-compose up --build`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright 2022 New Relic Corporation. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
'use strict' | ||
|
||
module.exports = { | ||
extends: '@newrelic', | ||
parserOptions: { | ||
ecmaVersion: 'latest' | ||
}, | ||
rules: { | ||
'no-console': 'off', | ||
'func-names': 'off' | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright 2023 New Relic Corporation. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import DataLoader from 'dataloader' | ||
import { getUserById } from './datastore.js' | ||
|
||
const loaders = () => ({ | ||
getUserById: new DataLoader( | ||
(ids) => { | ||
return Promise.all(ids.map((id) => getUserById(Number(id)))) | ||
}, | ||
{ | ||
batchScheduleFn: (callback) => setTimeout(callback, 100) | ||
} | ||
) | ||
}) | ||
|
||
const getContext = () => { | ||
return { | ||
loaders: loaders() | ||
} | ||
} | ||
|
||
export default getContext |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* Copyright 2023 New Relic Corporation. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { | ||
DynamoDBClient as Client, | ||
CreateTableCommand, | ||
DeleteTableCommand, | ||
waitUntilTableExists, | ||
waitUntilTableNotExists | ||
} from '@aws-sdk/client-dynamodb' | ||
import { DynamoDBDocumentClient, GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb' | ||
import { generateUsers } from './utils.js' | ||
|
||
const tableParams = { | ||
AttributeDefinitions: [ | ||
{ | ||
AttributeName: 'id', | ||
AttributeType: 'N' | ||
} | ||
], | ||
KeySchema: [ | ||
{ | ||
AttributeName: 'id', | ||
KeyType: 'HASH' | ||
} | ||
], | ||
ProvisionedThroughput: { | ||
ReadCapacityUnits: 1, | ||
WriteCapacityUnits: 1 | ||
}, | ||
TableName: 'Users', | ||
StreamSpecification: { | ||
StreamEnabled: false | ||
} | ||
} | ||
|
||
async function initData() { | ||
const client = new Client({}) | ||
try { | ||
console.log('Deleting table...') | ||
await client.send(new DeleteTableCommand({ TableName: 'Users' })) | ||
await waitUntilTableNotExists({ client }, { TableName: 'Users' }) | ||
} catch (err) { | ||
console.log(err.message) | ||
} | ||
console.log('Creating table...') | ||
await client.send(new CreateTableCommand(tableParams)) | ||
await waitUntilTableExists({ client }, { TableName: 'Users' }) | ||
|
||
console.log('Adding users...') | ||
const docClient = DynamoDBDocumentClient.from(client) | ||
const users = generateUsers(10) | ||
for (const user of users) { | ||
user.id = user._id | ||
await docClient.send( | ||
new PutCommand({ | ||
TableName: 'Users', | ||
Item: user | ||
}) | ||
) | ||
} | ||
console.log('added 10 users') | ||
} | ||
|
||
async function getUserById(id) { | ||
const client = DynamoDBDocumentClient.from(new Client({})) | ||
const { Item: item } = await client.send( | ||
new GetCommand({ | ||
TableName: 'Users', | ||
Key: { id } | ||
}) | ||
) | ||
return item | ||
} | ||
|
||
export { getUserById, initData } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright 2023 New Relic Corporation. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { MongoClient } from 'mongodb' | ||
import { generateUsers } from './utils.js' | ||
|
||
async function initData() { | ||
const client = new MongoClient(process.env.MONGO_URL) | ||
try { | ||
await client.connect() | ||
const allUsers = generateUsers(10) | ||
const db = client.db('users') | ||
const friends = db.collection('friends') | ||
await friends.deleteMany() | ||
|
||
const result = await friends.insertMany(allUsers, { ordered: true }) | ||
console.log(`${result.insertedCount} users were created`) | ||
} finally { | ||
client.close() | ||
} | ||
} | ||
|
||
async function getUserById(id) { | ||
console.log(`Fetch user #${id}`) | ||
const client = new MongoClient(process.env.MONGO_URL) | ||
try { | ||
await client.connect() | ||
const db = client.db('users') | ||
const friends = db.collection('friends') | ||
const result = await friends.findOne({ _id: id }) | ||
console.log(result) | ||
return result | ||
} finally { | ||
client.close() | ||
} | ||
} | ||
|
||
export { getUserById, initData } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright 2023 New Relic Corporation. All rights reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import * as dynamodb from './datastore-dynamodb.js' | ||
import * as mongo from './datastore-mongo.js' | ||
|
||
async function initData() { | ||
if (process.env.NEW_RELIC_DATASTORE.toLowerCase() === 'dynamodb') { | ||
return await dynamodb.initData() | ||
} | ||
if (process.env.NEW_RELIC_DATASTORE.toLowerCase() === 'mongo') { | ||
return await mongo.initData() | ||
} | ||
throw new Error( | ||
'Unknown datastore. Set the "NEW_RELIC_DATASTORE" environment variable to either "DynamoDB" or "Mongo"' | ||
) | ||
} | ||
|
||
async function getUserById(id) { | ||
if (process.env.NEW_RELIC_DATASTORE.toLowerCase() === 'dynamodb') { | ||
return await dynamodb.getUserById(id) | ||
} | ||
if (process.env.NEW_RELIC_DATASTORE.toLowerCase() === 'mongo') { | ||
return await mongo.getUserById(id) | ||
} | ||
throw new Error( | ||
'Unknown datastore. Set the "NEW_RELIC_DATASTORE" environment variable to either "DynamoDB" or "Mongo"' | ||
) | ||
} | ||
|
||
export { getUserById, initData } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
shopt -s expand_aliases | ||
|
||
alias http='http --print b --ignore-stdin' | ||
|
||
echo "Starting request loop" | ||
while true; do | ||
|
||
# Get all users | ||
echo "Fetching all users" | ||
http localhost:4000 query='{allUsers{age, email, hobbies, id, name, friends}}' | jq -C | ||
|
||
for id in {1..10}; do | ||
echo "Fetching user #${id}" | ||
http localhost:4000 query="{user(id:${id}){age, email, hobbies, id, name, friends}}" | jq -C | ||
done | ||
sleep 5 | ||
done |
Oops, something went wrong.