Skip to content

Commit 6047cc5

Browse files
committed
use dynamoose/dynamodb instead of knex
1 parent 2bf81ab commit 6047cc5

File tree

8 files changed

+324
-402
lines changed

8 files changed

+324
-402
lines changed

.npmrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
2+
@trunkclub:registry=https://registry.npmjs.org/
3+
4+
save-exact=true

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@types/faker": "4.1.12",
2121
"@types/graphql": "14.5.0",
2222
"@types/node": "14.0.13",
23+
"@types/uuid": "^8.3.0",
2324
"graphql-schema-typescript": "1.3.2",
2425
"jest": "26.0.1",
2526
"serverless": "2.3.0",
@@ -34,11 +35,12 @@
3435
"dependencies": {
3536
"apollo-server-lambda": "2.18.1",
3637
"camelcase": "^6.0.0",
38+
"dynamoose": "^2.3.0",
3739
"faker": "^4.1.0",
3840
"graphql": "15.1.0",
39-
"knex": "0.21.6",
4041
"knex-stringcase": "^1.4.1",
41-
"pg": "^8.2.0",
42-
"snake-case": "^3.0.3"
42+
"snake-case": "^3.0.3",
43+
"ts-node": "^9.0.0",
44+
"uuid": "^8.3.1"
4345
}
4446
}

serverless.yml

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,31 @@ service: graphql-nodejs
77
plugins:
88
- serverless-webpack
99
- serverless-offline
10-
- serverless-dotenv-plugin
1110

1211
# serverless-webpack configuration
1312
# Enable auto-packing of external modules
1413
custom:
1514
webpack:
1615
webpackConfig: ./webpack.config.js
1716
includeModules: true
18-
dotenv:
19-
exclude:
20-
- AWS_ACCESS_KEY
21-
- AWS_SECRET_KEY
2217

2318
provider:
2419
name: aws
2520
runtime: nodejs12.x
2621
stage: dev
2722
region: us-east-1
23+
iamRoleStatements:
24+
- Effect: Allow
25+
Action:
26+
# Dynamoose uses DescribeTable ensure the table doesn't already exist.
27+
- dynamodb:DescribeTable
28+
- dynamodb:Query
29+
- dynamodb:Scan
30+
- dynamodb:GetItem
31+
- dynamodb:PutItem
32+
- dynamodb:UpdateItem
33+
- dynamodb:DeleteItem
34+
Resource: 'arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/Todos'
2835

2936
functions:
3037
graphql:
@@ -38,3 +45,19 @@ functions:
3845
- http:
3946
path: graphql
4047
method: get
48+
resources:
49+
Resources:
50+
TodosTable:
51+
Type: 'AWS::DynamoDB::Table'
52+
DeletionPolicy: Retain
53+
Properties:
54+
AttributeDefinitions:
55+
- AttributeName: id
56+
AttributeType: S
57+
KeySchema:
58+
- AttributeName: id
59+
KeyType: HASH
60+
ProvisionedThroughput:
61+
ReadCapacityUnits: 1
62+
WriteCapacityUnits: 1
63+
TableName: Todos

src/resolvers/client.ts

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
import knex from 'knex'
1+
import dynamoose from 'dynamoose'
22

3-
import { convertToCamel } from '../utils'
3+
dynamoose.aws.sdk.config.update({
4+
region: 'us-east-1',
5+
})
46

5-
const client = knex({
6-
client: 'postgres',
7-
connection: {
8-
host: process.env.DB_HOST,
9-
user: process.env.DB_USER,
10-
password: process.env.DB_PASSWORD,
11-
database: process.env.DB_NAME,
12-
},
13-
postProcessResponse: (result, queryContext) => {
14-
if (Array.isArray(result)) {
15-
return result.map((row) => convertToCamel(row))
16-
} else if (typeof result === 'object') {
17-
return convertToCamel(result)
18-
} else {
19-
return result
20-
}
7+
const todoSchema = new dynamoose.Schema(
8+
{
9+
id: {
10+
type: String,
11+
hashKey: true,
12+
},
13+
body: String,
14+
completed: Boolean,
2115
},
22-
})
16+
{ timestamps: true },
17+
)
18+
19+
const TodoClient = dynamoose.model('Todos', todoSchema, { create: false })
2320

24-
export default client
21+
export { TodoClient }

src/resolvers/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { getTodos } from './query'
2-
import { createTodo, deleteTodo, completeTodo } from './mutation'
2+
import { createTodo, completeTodo, deleteTodo } from './mutation'
33
import { Resolvers } from 'generated/graphql'
44

55
const resolvers: Resolvers = {
66
Query: {
7-
getTodos,
7+
getTodos: getTodos,
88
},
99
Mutation: {
1010
createTodo: async (_, { input }) => await createTodo(input),

src/resolvers/mutation.ts

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,32 @@
1-
import faker from 'faker'
2-
import client from './client'
3-
import { convertToSnake } from '../utils'
1+
// import faker from 'faker'
2+
import { TodoClient } from './client'
43
import { TodoInput, Todo } from 'generated/graphql'
4+
import { v4 as uuidv4 } from 'uuid'
55

66
export const createTodo = async (input: TodoInput): Promise<Todo> => {
7-
return (
8-
await client
9-
.insert(convertToSnake(input))
10-
.into<Todo>('todos')
11-
.returning('*')
12-
)[0]
7+
const newTodo = new TodoClient({
8+
id: uuidv4(),
9+
completed: false,
10+
...input,
11+
})
12+
13+
return await newTodo.save().then((data) => data.toJSON() as Todo)
1314
}
1415

1516
export const deleteTodo = async (id: string) => {
16-
const numRowsAffected = await client.from<Todo>('todos').where({ id }).del()
17-
18-
if (!numRowsAffected) {
17+
try {
18+
await TodoClient.delete({ id })
19+
return id
20+
} catch (e) {
1921
throw 'No todos have been deleted!'
2022
}
21-
22-
return id
2323
}
2424

2525
export const completeTodo = async (id: string) => {
2626
try {
27-
const { id: completedTodoId } = await client
28-
.from<Todo>('todos')
29-
.where('id', id)
30-
.update<'id', Pick<Todo, 'id'>>({ completed: true }, ['id'])
31-
32-
if (!completedTodoId) {
33-
throw 'Unable to complete todo item'
34-
}
27+
await TodoClient.update({ id }, { completed: true })
3528

36-
return completedTodoId
29+
return id
3730
} catch (e) {
3831
throw e
3932
}

src/resolvers/query.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import client from './client'
1+
import { TodoClient } from './client'
22
import { Todo } from 'generated/graphql'
33

4-
export const getTodos = async () => await client<Todo>('todos').select()
4+
export const getTodos = async () => {
5+
const data = await TodoClient.scan().exec()
6+
7+
return data.toJSON() as Array<Todo>
8+
}

0 commit comments

Comments
 (0)