Building my own bookmarks service - Part 2
Creating a GraphQL service for retrieving our bookmarks
Posted: Monday, August 30 2021 1:53 pmUpdated: Monday, August 30 2021 2:17 pmThis holiday weekend I decided that it would be a great idea to build my own bookmarks service.
This bookmarks service starts with the Inbox Service would receive an email from SES, categorise that email and output JSON to a specific folder in a bucket.
Then there’s another service that gets triggered when that file has been saved and will process the data from the JSON and then store that processed data in DynamoDB.
In this article, I’m going to be building a new GraphQL API layer, this layer will provide us with a platform to retrieve and update the bookmarks.
You can find the full code for my Bookmarks Service here: https://github.com/nicholasgriffintn/Bookmarks-Service
Updating our Serverless definition
The first step in making our new GraphQL API is to update the Serverless definition that we made in part one to include our new GraphQL API.
This is done like so:
1functions: 2 process: 3 handler: processor.process 4 description: Process Bookmark emails to DynamoDB 5 timeout: 15 6 events: 7 - s3: 8 bucket: email.nicholasgriffin.dev 9 event: s3:ObjectCreated:* 10 rules: 11 - prefix: processed/bookmarks/ 12 - suffix: .json 13 existing: true 14 graphql: 15 handler: api.graphql 16 description: GraphQL Service for interacting with the bookmarks data 17 timeout: 15 18 events: 19 - http: 20 path: graphql 21 method: post 22 cors: true 23 - http: 24 path: graphql 25 method: get 26 cors: true 27
If you read the previous article, you may have also noticed that I have moved the processor and the API into their own files to keep things a little tidier.
Aside from what we did in part 1, that should be all you need to do here.
Setting up the API
Next up, in our api file, we need to import a few packages that will help us along the way, these are:
1const { ApolloServer, gql } = require('apollo-server-lambda'); 2const { unmarshall } = require('@aws-sdk/util-dynamodb'); 3const { DynamoDBClient, ScanCommand } = require('@aws-sdk/client-dynamodb'); 4
We also need to define our DynamoDB Client which will be used for grabbing the bookmarks data.
1const client = new DynamoDBClient({ region: config.region }); 2
Now that’s done, let’s define our schema for GraphQL to use, at the moment, I’m defining everything as a string for the sake of time, but I’m going to need to change the bookmark to a proper object when I have the time.
For now, our schema is this:
1const typeDefs = gql' 2 scalar JSON 3 type Bookmark { 4 id: String! 5 status: String 6 subject: String 7 recieved: String 8 bookmark: String 9 toName: String 10 toAddress: String 11 fromName: String 12 fromAddress: String 13 } 14 type Query { 15 bookmarks: [Bookmark] 16 } 17'; 18
Next up are the resolvers, this is quite simple for now as we are only adding a retrieve function, we’ll want to update this with our mutations later.
1const resolvers = { 2 Query: { 3 bookmarks: () => { 4 return getBookmarks(); 5 } 6 } 7}; 8
The getBookmarks function that we are returning is this:
1const getBookmarks = async () => { 2 const params = { 3 TableName: config.tableName, 4 }; 5 6 try { 7 const results = await client.send(new ScanCommand(params)); 8 const bookmarks = []; 9 results.Items.forEach((item) => { 10 const newRecord = unmarshall(item); 11 12 bookmarks.push(newRecord); 13 }); 14 return bookmarks; 15 } catch (err) { 16 console.error(err); 17 return err; 18 } 19}; 20
Now that’s done, we just need to create the server and export the handler that Serverless will be using:
1const gqlServer = new ApolloServer({ 2 typeDefs, 3 resolvers, 4 introspection: false, 5}); 6 7module.exports.graphql = gqlServer.createHandler({ 8 cors: { 9 origin: true, 10 credentials: true, 11 }, 12}); 13
And that’s about it, we now have a GraphQL server that can output the data from our Bookmarks in DynamoDB!
In the next part, I’ll be expanding this service while I build a frontend for this service that will display all of the verified bookmarks and allow me to verify bookmarks that have not yet been verified from my Cognito login.
So stay tuned for that.
You must accept my use of cookies before you can comment or read comments! Please refresh this page if you have accepted cookies and this still shows.