├── .gitignore ├── package.json ├── README.md ├── weather └── index.js └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "key_relay_tut", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "dev": "nodemon index.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "cors": "^2.8.5", 15 | "dotenv": "^8.2.0", 16 | "express": "^4.17.1", 17 | "express-rate-limit": "^5.2.6", 18 | "node-fetch": "^2.6.1" 19 | }, 20 | "devDependencies": { 21 | "nodemon": "^2.0.7" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NodeJS API Key Relay 2 | 3 | [![Remix on Glitch](https://cdn.glitch.com/2703baf2-b643-4da7-ab91-7ee2a2d00b5b%2Fremix-button.svg)](https://glitch.com/edit/#!/import/github/gitdagray/node_api_key_relay) 4 | 5 | **Start by clicking the Remix on Glitch button above.** 6 | 7 | [YouTube Tutorial](https://youtu.be/uk9pviyvrtg) for this repository. 8 | 9 | Add your API Keys to the .env file you will find on Glitch after launching this code by using the button above. 10 | 11 | Modify the code in your Glitch project to add your own custom API endpoints. 12 | 13 | You can host this NodeJS project elsewhere, but Glitch makes it easy. 14 | 15 | Never include your .env file in a GitHub repository. Add _.env_ to your _.gitignore_ file before pushing a project to GitHub. 16 | 17 | ### Academic Honesty 18 | 19 | **DO NOT COPY** - Avoid plagiargism and adhere to the spirit of this [Academic Honesty Policy](https://www.freecodecamp.org/news/academic-honesty-policy/). 20 | -------------------------------------------------------------------------------- /weather/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const fetch = require("node-fetch"); 4 | 5 | const fetchWeather = async (searchtext) => { 6 | const url = `https://api.openweathermap.org/data/2.5/weather?q=${searchtext}&units=imperial&appid=${process.env.WEATHER_API_KEY}`; 7 | try { 8 | const weatherStream = await fetch(url); 9 | const weatherJson = await weatherStream.json(); 10 | return weatherJson; 11 | } catch (err) { 12 | return { Error: err.stack }; 13 | } 14 | }; 15 | 16 | router.get("/", (req, res) => { 17 | res.json({ success: "Hello Weather!" }); 18 | }); 19 | 20 | router.get("/:searchtext", async (req, res) => { 21 | const searchtext = req.params.searchtext; 22 | const data = await fetchWeather(searchtext); 23 | res.json(data); 24 | }); 25 | 26 | router.post("/", async (req, res) => { 27 | const searchtext = req.body.searchtext; 28 | const data = await fetchWeather(searchtext); 29 | res.json(data); 30 | }); 31 | 32 | module.exports = router; 33 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | const express = require("express"); 3 | const rateLimit = require("express-rate-limit"); 4 | const cors = require("cors"); 5 | const app = express(); 6 | const port = 3000; 7 | 8 | const weather = require("./weather"); 9 | 10 | app.use(express.json()); 11 | 12 | // Use if you're behind a reverse proxy 13 | // https://expressjs.com/en/guide/behind-proxies.html 14 | // app.set('trust proxy', 1); 15 | 16 | const whitelist = ["http://127.0.0.1", "http://127.0.0.1:5500"]; 17 | const corsOptions = { 18 | origin: (origin, callback) => { 19 | if (!origin || whitelist.indexOf(origin) !== -1) { 20 | callback(null, true); 21 | } else { 22 | callback(new Error("Not allowed by CORS")); 23 | } 24 | }, 25 | optionsSuccessStatus: 200 26 | }; 27 | 28 | app.use(cors(corsOptions)); 29 | 30 | // If needed: Allow options to pass CORS preflight check 31 | /* app.options("/*", (req, res, next) => { 32 | res.header("Access-Control-Allow-Origin", "*"); 33 | res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS"); 34 | res.header( 35 | "Access-Control-Allow-Headers", 36 | "Content-Type,Authorization,Content-Length,X-Requested-With" 37 | ); 38 | res.sendStatus(200); 39 | }); */ 40 | 41 | const limiter = rateLimit({ 42 | windowMs: 1000, 43 | max: 1 44 | }); 45 | app.use(limiter); 46 | 47 | //test route 48 | app.get("/", (req, res) => res.json({ success: "Hello World!" })); 49 | 50 | app.use("/weather", weather); 51 | 52 | app.listen(port, () => console.log(`App listening on port ${port}`)); 53 | --------------------------------------------------------------------------------