Sådan integreres DynamoDB i din API ved hjælp af AWS Lambda

I den første del af denne vejledning oprettede vi en API, der sendte anmodninger videre til en Lambda, som returnerede det bedste tv-show eller film for den genre. Nu skal vi bruge DynamoDB til at give brugerne mulighed for at stemme på deres yndlingsgenre.

Hvis du ikke har læst den første del af denne serie, så tjek den her!

DynamoDB

DynamoDB er en ikke-relationel database oprettet af Amazon, som vi kan bruge til at gemme brugernes stemmer. Det er også godt, fordi vi let kan få adgang til det ved hjælp af aws-sdksom Lambdas har forudinstalleret.

Den første ting, vi skal gøre, er at oprette en tabel til opbevaring af filmstemmerne. Naviger til DynamoDB i AWS, og klik på "Opret tabel".

På den næste side navngiver vi vores tabel og giver en primær nøgle. Den primære nøgle skal være unik, så vi ikke har to poster med den samme nøgle. Vi kan kalde tabellen "film-api" og indstille den primære nøgle til "film-genre", da hver film kun skal vises en gang i hver genre.

Vi har nu konfigureret alt det, vi har brug for for at oprette i DynamoDB, så vi kan gå tilbage til vores kode.

Tilføjelse af en Dynamo-handler

At få og sætte data i en Dynamo-tabel udføres ved hjælp af documentClienton aws-sdk , men anmodningenes struktur er meget specifik. For at gøre vores liv lettere kan vi få en Dynamo-handler til at udføre al formatering.

Start med at oprette en ny fil kaldet “dynamo.js” i “movieAPI” Lambda. I denne fil starter vi med at kræve aws-sdk og oprette vores documentClient.

const AWS = require('aws-sdk');
let documentClient = new AWS.DynamoDB.DocumentClient({ 'region': 'eu-west-1'});

Vi vil nu oprette og eksportere en klasse, der har tre metoder: a get, a writeog an update.

module.exports = class DB { get(key, value, table) {} write(ID, data, table) {} async increment(ID, table) {}}

Vi starter med at oprette vores getmetode. Det første, vi skal gøre, er at kontrollere, at vi har et gyldigt key,value og table.

if (!table) throw 'table needed';if (typeof key !== 'string') throw `key was not string and was ${JSON.stringify(key)} on table ${table}`;if (typeof value !== 'string') throw `value was not string and was ${JSON.stringify(value)} on table ${table}`;

Fordi vi ønsker, at denne metode skal være løftebaseret, skal vi returnere en new Promise.

return new Promise((resolve, reject) => {})

For at få data fra Dynamo er vi nødt til at videregive et sæt parametre til dokumentklienten. Disse paramider skal inkludere TableNameogKey.

let params = { TableName: table, Key: {[key]: value}};

Vi videregiver disse params tildocumentClientog så rejecthvis der er en fejl ellerresolvehvis der ikke er.

documentClient.get(params, function(err, data) { if (err) { console.log(`There was an error fetching the data for ${key} ${value} on table ${table}`, err); return reject(err); } return resolve(data.Item);});

En lignende proces udføres for writemetoden. Vi kontrollerer, at parametrene er gyldige, opretter parametrene og videregiver dem til documentClient.

return new Promise((resolve, reject) => { if (typeof ID !== 'string') throw `the id must be a string and not ${ID}`; if (!data) throw "data is needed"; if (!table) throw 'table name is needed';
 let params = { TableName: table, Item: { ...data, ID: ID } };
 documentClient.put(params, function(err, result) { if (err) { console.log("Err in writeForCall writing messages to dynamo:", err); console.log(params); return reject(err); } console.log('wrote data to table ', table) return resolve({ ...result.Attributes, ...params.Item }); });});

Den incrementmetode er meget nemmere. For at inkrementere prøver vi at hente dataene til den nøgle, øge antallet af en og derefter skrive dem tilbage til databasen. Hvis vi ikke kan få dataene, eller hvis der ikke tælles på dataene, antager vi, at vi skal indstille optællingen til 0.

async increment(ID, table) { if (!table) throw 'table needed'; if (!ID) throw 'ID needed'; let data; try { data = await this.get('movie-genre', ID, table); if (!data.count) throw 'no count in data' } catch (err) { data = { "movie-genre": ID, count: 0 }; }; let newData = { ...data, count: data.count + 1 }; return this.write(ID, newData, table);}

Ændring af vores Lambda

Nu har vi en nem måde at få, skrive og opdatere vores Dynamo-tabel på. Vi kan bruge dette til at give vores brugere mulighed for at stemme. Inde i "index.js",vi skal først importere vores nye Dynamo-klasse og oprette en forekomst af den.

const DB = require('./dynamo');const Dynamo = new DB();

Nu inde i vores putMovievi kan tilføje logikken for at give brugerne mulighed for at stemme. De to ting, vi skal få, er moviefra kroppen og genrefra stiparametrene. Vi kombinerer derefter disse for at skabe voresmovie-genreID. Dette sendes derefter ind Dynamo.incrementmed et tabelnavn på, movie-apiog vores putMovieer komplet.

const putMovie = async event => { let { movie } = JSON.parse(event.body); let genre = event.pathParameters.genre; let ID = `${movie}-${genre}`; return Dynamo.increment(ID, 'movie-api')}

For at få dette til at fungere, når vi modtager Putanmodning, er vi nødt til at ændre vores basehåndteringsfunktion lidt.

if (event.httpMethod === 'PUT') { let response = await putMovie(event) return done(response);}

Fordi vi har tilføjet AWS til vores Lambda, skal vi køre npm initog derefter npm install — save aws-sdki Lambda-mappen. Dette kan gøres lokalt og uploades eller gøres ved hjælp af Cloud9.

Tilføjelse af API Gateway-metoden

Med den nye funktion kan vi tilføje en ny metode til vores API. I API Gateway kan vi vælge vores "movieAPI" og derefter vælge "/ film / {genre}" . Klik på "Handlinger" -> "Opret meth o d", og vælg at tilføje en "PUT" -metode.

Denne ”PUT” kan være rettet mod vores ”movieAPI” , og kryds ”Brug Lambda Proxy integration”. Når vi er gemt, kan vi teste det. På metoden kan vi klikke på "TEST" og indtaste en genre og et organ, der indeholder en film. Når vi klikker på "TEST", får vi et svar, der indeholder filmen og det nye antal. Da dette er den første afstemning, vil antallet være 1.

Hvis du kører testen en anden gang, øges stemmerne til denne film nu én.

Ændring af GET- metoden

Nu hvor vi har et nyt stemmesystem, kan vi opdatere vores "GET"at bruge disse nye data. Vi er nødt til at få alle de film, der er i den anmodede genre, og liste dem i rækkefølge efter stemmerne.

Vi skal først lave en ny dynamometode. Denne metode scanner hver af posterne og vælger dem, der matcher vores kriterier.

scan(key, value, table) { return new Promise((resolve, reject) => { let params = { TableName: table, FilterExpression: `${key} = :value`, ExpressionAttributeValues: { ':value': value } }; documentClient.scan(params, function(err, data) { if (err) reject(err); resolve(data); }); });}

Vi kan nu ændre vores getMoviefunction to use this new Dynamo method. We need to pass the genre, selected movie, and current count.

const getMovie = async event => { let genre = event.pathParameters.genre; let data = await Dynamo.scan('genre', genre, 'movie-api'); let result = data.Items.sort((a,b) => b.count - a.count); result = result.map(({count, ID, genre})=> { return {count, ID, genre}}); return data;}

The last thing to do is to add an await before out getMoviefunction so that it handles the async database scan.

let response = await getMovie(event);

Testing

When we hit this new “GET” endpoint we receive an ordered list of all of the movies in the database.

[ { "count": 2, "ID": "Desperado (1995)-action", "genre": "action" }, { "count": 1, "ID": "Team America (2004)-action", "genre": "action" }]

Summary

We’ve now built an API that can handle “GET” and “PUT” requests, storing and retrieving data from a Dynamo database. You can also reuse a lot of the Dynamo class code for other APIs that work with Dynamo.

Want some practice?

If you’ve enjoyed this, then why not try to implement a similar setup for tv shows? If you do, then let me know how it goes!

You can also improve this API by making sure that Desperado (1995) and desperado (1995) both count towards the same movie, or only allow a certain format of movie title.

Hvis du har ønsket dette, skal du sørge for at give det et klapp og abonnere på flere Amazon-vejledninger og vejledninger. Vi ses i den næste artikel og Keep Coding!