Import cities data to mongodb
mongoimport --db=cities --collection=cities --file=./zips.json
Generate API doc
npm install apidoc -g
apidoc -f "routes/.*\\.js$" -i ./ -o apidoc/
npm install && npm start
open http://localhost:3000/apidoc/index.html
Start the consul service discovery agent
consul agent -dev -ui -node mynode
- a.
- http://data.fixer.io/api/latest?access_key=b3d7da73f67deeebf0a45464f9f49c8e&format=1
- https://www.liquid-technologies.com/online-json-to-schema-converter
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"timestamp": {
"type": "integer"
},
"base": {
"type": "string"
},
"date": {
"type": "string"
},
"rates": {
"type": "object",
"properties": {
"AED": {
"type": "number"
},
"AFN": {
"type": "number"
},
"ALL": {
"type": "number"
},
"AMD": {
"type": "number"
},
"ANG": {
"type": "number"
},
"AOA": {
"type": "number"
},
"ARS": {
"type": "number"
},
"AUD": {
"type": "number"
},
"AWG": {
"type": "number"
},
"AZN": {
"type": "number"
},
"BAM": {
"type": "number"
},
"BBD": {
"type": "number"
},
"BDT": {
"type": "number"
},
"BGN": {
"type": "number"
},
"BHD": {
"type": "number"
},
"BIF": {
"type": "number"
},
"BMD": {
"type": "number"
},
"BND": {
"type": "number"
},
"BOB": {
"type": "number"
},
"BRL": {
"type": "number"
},
"BSD": {
"type": "number"
},
"BTC": {
"type": "number"
},
"BTN": {
"type": "number"
},
"BWP": {
"type": "number"
},
"BYN": {
"type": "number"
},
"BYR": {
"type": "number"
},
"BZD": {
"type": "number"
},
"CAD": {
"type": "number"
},
"CDF": {
"type": "number"
},
"CHF": {
"type": "number"
},
"CLF": {
"type": "number"
},
"CLP": {
"type": "number"
},
"CNY": {
"type": "number"
},
"COP": {
"type": "number"
},
"CRC": {
"type": "number"
},
"CUC": {
"type": "number"
},
"CUP": {
"type": "number"
},
"CVE": {
"type": "number"
},
"CZK": {
"type": "number"
},
"DJF": {
"type": "number"
},
"DKK": {
"type": "number"
},
"DOP": {
"type": "number"
},
"DZD": {
"type": "number"
},
"EGP": {
"type": "number"
},
"ERN": {
"type": "number"
},
"ETB": {
"type": "number"
},
"EUR": {
"type": "integer"
},
"FJD": {
"type": "number"
},
"FKP": {
"type": "number"
},
"GBP": {
"type": "number"
},
"GEL": {
"type": "number"
},
"GGP": {
"type": "number"
},
"GHS": {
"type": "number"
},
"GIP": {
"type": "number"
},
"GMD": {
"type": "number"
},
"GNF": {
"type": "number"
},
"GTQ": {
"type": "number"
},
"GYD": {
"type": "number"
},
"HKD": {
"type": "number"
},
"HNL": {
"type": "number"
},
"HRK": {
"type": "number"
},
"HTG": {
"type": "number"
},
"HUF": {
"type": "number"
},
"IDR": {
"type": "number"
},
"ILS": {
"type": "number"
},
"IMP": {
"type": "number"
},
"INR": {
"type": "number"
},
"IQD": {
"type": "number"
},
"IRR": {
"type": "number"
},
"ISK": {
"type": "number"
},
"JEP": {
"type": "number"
},
"JMD": {
"type": "number"
},
"JOD": {
"type": "number"
},
"JPY": {
"type": "number"
},
"KES": {
"type": "number"
},
"KGS": {
"type": "number"
},
"KHR": {
"type": "number"
},
"KMF": {
"type": "number"
},
"KPW": {
"type": "number"
},
"KRW": {
"type": "number"
},
"KWD": {
"type": "number"
},
"KYD": {
"type": "number"
},
"KZT": {
"type": "number"
},
"LAK": {
"type": "number"
},
"LBP": {
"type": "number"
},
"LKR": {
"type": "number"
},
"LRD": {
"type": "number"
},
"LSL": {
"type": "number"
},
"LTL": {
"type": "number"
},
"LVL": {
"type": "number"
},
"LYD": {
"type": "number"
},
"MAD": {
"type": "number"
},
"MDL": {
"type": "number"
},
"MGA": {
"type": "number"
},
"MKD": {
"type": "number"
},
"MMK": {
"type": "number"
},
"MNT": {
"type": "number"
},
"MOP": {
"type": "number"
},
"MRO": {
"type": "number"
},
"MUR": {
"type": "number"
},
"MVR": {
"type": "number"
},
"MWK": {
"type": "number"
},
"MXN": {
"type": "number"
},
"MYR": {
"type": "number"
},
"MZN": {
"type": "number"
},
"NAD": {
"type": "number"
},
"NGN": {
"type": "number"
},
"NIO": {
"type": "number"
},
"NOK": {
"type": "number"
},
"NPR": {
"type": "number"
},
"NZD": {
"type": "number"
},
"OMR": {
"type": "number"
},
"PAB": {
"type": "number"
},
"PEN": {
"type": "number"
},
"PGK": {
"type": "number"
},
"PHP": {
"type": "number"
},
"PKR": {
"type": "number"
},
"PLN": {
"type": "number"
},
"PYG": {
"type": "number"
},
"QAR": {
"type": "number"
},
"RON": {
"type": "number"
},
"RSD": {
"type": "number"
},
"RUB": {
"type": "number"
},
"RWF": {
"type": "number"
},
"SAR": {
"type": "number"
},
"SBD": {
"type": "number"
},
"SCR": {
"type": "number"
},
"SDG": {
"type": "number"
},
"SEK": {
"type": "number"
},
"SGD": {
"type": "number"
},
"SHP": {
"type": "number"
},
"SLL": {
"type": "number"
},
"SOS": {
"type": "number"
},
"SRD": {
"type": "number"
},
"STD": {
"type": "number"
},
"SVC": {
"type": "number"
},
"SYP": {
"type": "number"
},
"SZL": {
"type": "number"
},
"THB": {
"type": "number"
},
"TJS": {
"type": "number"
},
"TMT": {
"type": "number"
},
"TND": {
"type": "number"
},
"TOP": {
"type": "number"
},
"TRY": {
"type": "number"
},
"TTD": {
"type": "number"
},
"TWD": {
"type": "number"
},
"TZS": {
"type": "number"
},
"UAH": {
"type": "number"
},
"UGX": {
"type": "number"
},
"USD": {
"type": "number"
},
"UYU": {
"type": "number"
},
"UZS": {
"type": "number"
},
"VEF": {
"type": "number"
},
"VND": {
"type": "number"
},
"VUV": {
"type": "number"
},
"WST": {
"type": "number"
},
"XAF": {
"type": "number"
},
"XAG": {
"type": "number"
},
"XAU": {
"type": "number"
},
"XCD": {
"type": "number"
},
"XDR": {
"type": "number"
},
"XOF": {
"type": "number"
},
"XPF": {
"type": "number"
},
"YER": {
"type": "number"
},
"ZAR": {
"type": "number"
},
"ZMK": {
"type": "number"
},
"ZMW": {
"type": "number"
},
"ZWL": {
"type": "number"
}
},
"required": [
"AED",
"AFN",
"ALL",
"AMD",
"ANG",
"AOA",
"ARS",
"AUD",
"AWG",
"AZN",
"BAM",
"BBD",
"BDT",
"BGN",
"BHD",
"BIF",
"BMD",
"BND",
"BOB",
"BRL",
"BSD",
"BTC",
"BTN",
"BWP",
"BYN",
"BYR",
"BZD",
"CAD",
"CDF",
"CHF",
"CLF",
"CLP",
"CNY",
"COP",
"CRC",
"CUC",
"CUP",
"CVE",
"CZK",
"DJF",
"DKK",
"DOP",
"DZD",
"EGP",
"ERN",
"ETB",
"EUR",
"FJD",
"FKP",
"GBP",
"GEL",
"GGP",
"GHS",
"GIP",
"GMD",
"GNF",
"GTQ",
"GYD",
"HKD",
"HNL",
"HRK",
"HTG",
"HUF",
"IDR",
"ILS",
"IMP",
"INR",
"IQD",
"IRR",
"ISK",
"JEP",
"JMD",
"JOD",
"JPY",
"KES",
"KGS",
"KHR",
"KMF",
"KPW",
"KRW",
"KWD",
"KYD",
"KZT",
"LAK",
"LBP",
"LKR",
"LRD",
"LSL",
"LTL",
"LVL",
"LYD",
"MAD",
"MDL",
"MGA",
"MKD",
"MMK",
"MNT",
"MOP",
"MRO",
"MUR",
"MVR",
"MWK",
"MXN",
"MYR",
"MZN",
"NAD",
"NGN",
"NIO",
"NOK",
"NPR",
"NZD",
"OMR",
"PAB",
"PEN",
"PGK",
"PHP",
"PKR",
"PLN",
"PYG",
"QAR",
"RON",
"RSD",
"RUB",
"RWF",
"SAR",
"SBD",
"SCR",
"SDG",
"SEK",
"SGD",
"SHP",
"SLL",
"SOS",
"SRD",
"STD",
"SVC",
"SYP",
"SZL",
"THB",
"TJS",
"TMT",
"TND",
"TOP",
"TRY",
"TTD",
"TWD",
"TZS",
"UAH",
"UGX",
"USD",
"UYU",
"UZS",
"VEF",
"VND",
"VUV",
"WST",
"XAF",
"XAG",
"XAU",
"XCD",
"XDR",
"XOF",
"XPF",
"YER",
"ZAR",
"ZMK",
"ZMW",
"ZWL"
]
}
},
"required": [
"success",
"timestamp",
"base",
"date",
"rates"
]
}
b.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"definitions": {
"codes": {
"type": "string",
"enum": [
"AED",
"AFN",
"ALL",
"AMD",
"ANG",
"AOA",
"ARS",
"AUD",
"AWG",
"AZN",
"BAM",
"BBD",
"BDT",
"BGN",
"BHD",
"BIF",
"BMD",
"BND",
"BOB",
"BRL",
"BSD",
"BTC",
"BTN",
"BWP",
"BYN",
"BYR",
"BZD",
"CAD",
"CDF",
"CHF",
"CLF",
"CLP",
"CNY",
"COP",
"CRC",
"CUC",
"CUP",
"CVE",
"CZK",
"DJF",
"DKK",
"DOP",
"DZD",
"EGP",
"ERN",
"ETB",
"EUR",
"FJD",
"FKP",
"GBP",
"GEL",
"GGP",
"GHS",
"GIP",
"GMD",
"GNF",
"GTQ",
"GYD",
"HKD",
"HNL",
"HRK",
"HTG",
"HUF",
"IDR",
"ILS",
"IMP",
"INR",
"IQD",
"IRR",
"ISK",
"JEP",
"JMD",
"JOD",
"JPY",
"KES",
"KGS",
"KHR",
"KMF",
"KPW",
"KRW",
"KWD",
"KYD",
"KZT",
"LAK",
"LBP",
"LKR",
"LRD",
"LSL",
"LTL",
"LVL",
"LYD",
"MAD",
"MDL",
"MGA",
"MKD",
"MMK",
"MNT",
"MOP",
"MRO",
"MUR",
"MVR",
"MWK",
"MXN",
"MYR",
"MZN",
"NAD",
"NGN",
"NIO",
"NOK",
"NPR",
"NZD",
"OMR",
"PAB",
"PEN",
"PGK",
"PHP",
"PKR",
"PLN",
"PYG",
"QAR",
"RON",
"RSD",
"RUB",
"RWF",
"SAR",
"SBD",
"SCR",
"SDG",
"SEK",
"SGD",
"SHP",
"SLL",
"SOS",
"SRD",
"STD",
"SVC",
"SYP",
"SZL",
"THB",
"TJS",
"TMT",
"TND",
"TOP",
"TRY",
"TTD",
"TWD",
"TZS",
"UAH",
"UGX",
"USD",
"UYU",
"UZS",
"VEF",
"VND",
"VUV",
"WST",
"XAF",
"XAG",
"XAU",
"XCD",
"XDR",
"XOF",
"XPF",
"YER",
"ZAR",
"ZMK",
"ZMW",
"ZWL"
]
}
},
"properties": {
"success": {
"type": "boolean"
},
"timestamp": {
"type": "integer"
},
"base": {
"type": "string"
},
"date": {
"type": "string"
},
"rates": {
"$ref": "#/definitions/codes"
}
},
"required": [
"success",
"timestamp",
"base",
"date",
"rates"
]
}
2 a.
openapi: "3.0.2"
info:
title: "Exchange rate API"
description: "My API for exchange rate"
version: "v1.0"
servers:
- url: http://localhost:3000
description: "Development server"
- url: http://localhost:4000
description: "UAT server"
components:
schemas:
stateList:
description: "List of all the currency codes"
type: array
items:
$ref: "#/components/schemas/rates"
state:
description: "Currency Codes"
type: string
enum: [
... currency codes
]
paths:
/api/latest:
get:
description: "Returns a list of all the rates"
operationId: getRates
responses:
200:
description: "List of all rates"
content:
"application/json":
schema:
$ref: "#/components/schemas/rates"
b. Placing it on URL or header won't solve security risk. If SSL is enabled yes putting on header is safer.
- Precache with condition and using redis on the server side caching.
-
encryption - A typical example is the SSL certificate of a web server providing proof to the user that he or she is connected to the correct server. The identity is not of the user, but of the cryptographic key of the user. Having a less secure key lowers the trust we can place on the identity.
-
non repudiation - The concept of non-repudiation is particularly important for financial or e-commerce applications. Often, cryptographic tools are required to prove that a unique user has made a transaction request. It must not be possible for the user to refute his or her actions. For example, a customer may request a transfer of money from her account to be paid to another account. Later, she claims never to have made the request and demands the money be refunded to the account. If we have non-repudiation through cryptography, we can prove โ usually through digitally signing the transaction request, that the user authorized the transaction.
-
no tampering - We can use cryptography to provide a means to ensure data is not viewed or altered during storage or transmission. Cryptographic hashes for example, can safeguard data by providing a secure checksum.
b.
-
unique JWT identifier (jti) Unique identifier; can be used to prevent the JWT from being replayed (allows a token to be used only once)
-
cannot be used before a certain date (nbf) Time at which the JWT was issued; can be used to determine age of the JWT
-
issue date (iat) Time at which the JWT was issued; can be used to determine age of the JWT
iv. token recipient (aud) Recipient for which the JWT is intended
v. mobile number (phone_number_verified)
https://www.iana.org/assignments/jwt/jwt.xhtml#claims
-
Create Google account, create a google cloud platform project, generate oauth2 credentials, create callback URL, enable google calendar API.
-
I will be using a API gateway to front the service. Its either Kong or Express Gateway. Therefore with this approach I did not need to change the video API
https://www.express-gateway.io/getting-started/
- A single config to control it all
- Auto-detect and hot-reload config changes
- Plugin architecture
- A gateway for any language
- A gateway for any framework
- A gateway for all microservice use cases
- Built on Express Middleware and Node
- Pre-bundled with the most proven and popular modules
- Extend with any Express Middleware
- Run anywhere with Docker in your public or private cloud
- Works with any orchestrator and service mesh
- Plug into your DevOps tooling