· 6 years ago · Oct 10, 2019, 07:20 AM
1const express = require('express')
2const responseTime = require('response-time')
3const axios = require('axios')
4const redis = require('redis')
5const AWS = require('aws-sdk')
6
7const bucketName = 'andreasgarvik-wikipedia-store'
8
9const apiVersion = { apiVersion: '2006-03-01' }
10
11;(async () => {
12 try {
13 await new AWS.S3(apiVersion).createBucket({ Bucket: bucketName }).promise()
14 console.log('Successfully created ' + bucketName)
15 } catch (e) {
16 console.error('Could not connect to S3')
17 }
18})()
19
20const app = express()
21app.use(responseTime())
22
23const redisClient = redis.createClient()
24redisClient.on('error', err => {
25 console.log('Error ' + err)
26})
27
28app.get('/api/search', (req, res) => {
29 const query = req.query.query.trim()
30 const searchUrl = `https://en.wikipedia.org/w/api.php?action=parse&format=json§ion=0&page=${query}`
31 const redisKey = `wikipedia:${query}`
32 const s3Key = `wikipedia-${query}`
33
34 redisClient.get(redisKey, async (err, result) => {
35 if (result) {
36 res.status(200).json({ source: 'Redis Cache', ...JSON.parse(result) })
37 } else {
38 new AWS.S3(apiVersion).getObject(
39 { Bucket: bucketName, Key: s3Key },
40 async (err, result) => {
41 if (result) {
42 res
43 .status(200)
44 .json({ source: 'S3 Bucket', ...JSON.parse(result.Body) })
45 } else {
46 response = await getWiki(searchUrl)
47 await setS3(s3Key, response)
48 redisClient.setex(
49 redisKey,
50 3600,
51 JSON.stringify({ source: 'Redis Cache', ...response }),
52 () => console.log('Successfully stored data in redis')
53 )
54 res.status(200).json({ source: 'Wikipedia API', ...response })
55 }
56 }
57 )
58 }
59 })
60})
61
62const setS3 = async (s3Key, responseJSON) => {
63 const body = JSON.stringify({
64 source: 'S3 Bucket',
65 ...responseJSON
66 })
67 const objectParams = {
68 Bucket: bucketName,
69 Key: s3Key,
70 Body: body
71 }
72 await new AWS.S3(apiVersion).putObject(objectParams).promise()
73 console.log('Successfully uploaded data to ' + bucketName + '/' + s3Key)
74}
75
76const getWiki = async searchUrl => {
77 const response = await axios.get(searchUrl)
78 return response.data
79}
80
81app.get('/api/store', (req, res) => {
82 const key = req.query.key.trim()
83
84 // Construct the wiki URL and S3 key
85 const searchUrl = `https://en.wikipedia.org/w/api.php?action=parse&format=json§ion=0&page=${key}`
86 const s3Key = `wikipedia-${key}`
87 const params = { Bucket: bucketName, Key: s3Key }
88
89 return new AWS.S3(apiVersion).getObject(params, (err, result) => {
90 if (result) {
91 // Serve from S3
92 console.log(result)
93 const resultJSON = JSON.parse(result.Body)
94 return res.status(200).json(resultJSON)
95 } else {
96 // Serve from Wikipedia API and store in S3
97 return axios
98 .get(searchUrl)
99 .then(response => {
100 const responseJSON = response.data
101 const body = JSON.stringify({
102 source: 'S3 Bucket',
103 ...responseJSON
104 })
105 const objectParams = { Bucket: bucketName, Key: s3Key, Body: body }
106 const uploadPromise = new AWS.S3(apiVersion)
107 .putObject(objectParams)
108 .promise()
109
110 uploadPromise.then(function(data) {
111 console.log(
112 'Successfully uploaded data to ' + bucketName + '/' + s3Key
113 )
114 })
115 return res
116 .status(200)
117 .json({ source: 'Wikipedia API', ...responseJSON })
118 })
119 .catch(err => {
120 return res.json(err)
121 })
122 }
123 })
124})
125
126app.listen(3000, () => {
127 console.log('Server listening on port: 3000')
128})