diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..163b734
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,5 @@
+MYSQL_HOST=123.456.789.0
+MYSQL_USER=mydbAdmin
+MYSQL_PASSWORD=mydbAdminPassword
+MYSQL_DATABASE=world
+PORT=4000
diff --git a/DigiCertGlobalRootCA.crt.pem b/DigiCertGlobalRootCA.crt.pem
new file mode 100644
index 0000000..fd4341d
--- /dev/null
+++ b/DigiCertGlobalRootCA.crt.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
diff --git a/README.md b/README.md
index 4c2ba55..6ef5245 100644
--- a/README.md
+++ b/README.md
@@ -1,42 +1,95 @@
-# Node.js server with MySQL Template
+# Node.js Server with MySQL Template
## Table of Contents
- [Dependencies](#dependencies)
- [Installation](#installation)
-- [API specification](#API_specification)
+- [API Specification](#api-specification)
+- [Environment Configuration](#environment-configuration)
## Dependencies
-- dotenv
-- express
-- mysql2
+This project requires the following npm packages:
+
+- `dotenv` - For managing environment variables.
+- `express` - A web application framework for Node.js.
+- `mysql2` - MySQL client for Node.js, providing both callbacks and Promises API.
## Installation
-1. Clone the repo to your local machine
-2. Run `npm i`
-3. Create `.env` file, set up environment variables according to your Azure Database resource:
- `MYSQL_HOST = HostIPAddress/Domain`
- `MYSQL_USER = Username`
- `MYSQL_PASSWORD = YourPassword`
- `MYSQL_DATABASE = DatabaseName`
- `PORT = 4000`
-4. Get SSL Certificate `DigiCertGlobalRootCA.crt.pem` from Azure Database resource
-5. Start the server: `npm run dev`
+Follow these steps to set up the project on your local machine:
+
+1. **Clone the Repository:**
+ Run the following command to clone the repository to your local machine:
+ ```bash
+ git clone
+ ```
+
+2. **Install Dependencies:**
+ Navigate to the project directory and install the required dependencies using npm:
+ ```bash
+ npm install
+ ```
+
+3. **Configure Environment Variables:**
+ Create a `.env` file in the root directory of the project. Set up the following environment variables according to your Azure MySQL Database resource:
+ ```plaintext
+ MYSQL_HOST=HostIPAddress/Domain
+ MYSQL_USER=Username
+ MYSQL_PASSWORD=YourPassword
+ MYSQL_DATABASE=DatabaseName
+ PORT=4000
+ ```
+ - `MYSQL_HOST`: The IP address or domain name of your MySQL server.
+ - `MYSQL_USER`: The username for accessing the MySQL server.
+ - `MYSQL_PASSWORD`: The password for the above user.
+ - `MYSQL_DATABASE`: The name of the database you are connecting to.
+ - `PORT`: The port on which the Node.js server will listen.
+
+4. **Obtain SSL Certificate:**
+ Download the `DigiCertGlobalRootCA.crt.pem` SSL certificate from your Azure Database resource and place it in the project directory.
+
+5. **Start the Server:**
+ Run the following command to start the server in development mode:
+ ```bash
+ npm run dev
+ ```
+ The server should now be running and accessible at `http://localhost:4000`.
+
+## Environment Configuration
+
+### Using `.env` and `.env.example` Files
+
+- **`.env` File:**
+ The `.env` file is used to store environment-specific configurations such as database credentials, API keys, and other sensitive information. It should never be committed to the version control system (e.g., Git) for security reasons. Make sure to add `.env` to your `.gitignore` file.
+
+- **`.env.example` File:**
+ The `.env.example` file is a template version of the `.env` file. It should contain placeholders for all the environment variables used in the project but without actual sensitive values. This file can be safely committed to your repository and shared with your team to provide guidance on the required environment variables.
+
+ **Example of `.env.example`:**
+ ```plaintext
+ MYSQL_HOST=your_host_here
+ MYSQL_USER=your_username_here
+ MYSQL_PASSWORD=your_password_here
+ MYSQL_DATABASE=your_database_name_here
+ PORT=4000
+ ```
-## API specification
+ Each developer can copy the `.env.example` file to create their own `.env` file and fill in the actual values specific to their environment.
-Your API should conform to the following specifications.
+## API Specification
-### Show countries
+Your API should conform to the following specifications:
-Get a list of all properties currently listed.
+### 1. Show Countries
-**URL** : `/`
+Retrieve a list of all countries in the database.
-**Method** : `GET`
+- **URL** : `/`
+- **Method** : `GET`
+- **Response Format** : JSON
+**Example Response:**
```json
[
{
@@ -56,62 +109,60 @@ Get a list of all properties currently listed.
"Capital": 129,
"Code2": "AW"
},
- {
- ...
- }
- ,
...
]
```
----
-
-### Show the information about a specific country
-
-Get a single country.
+### 2. Show Information About a Specific Country
-**URL** : `/country/:countryname`
+Retrieve information about a single country based on its name.
-**Method** : `GET`
+- **URL** : `/country/:countryname`
+- **Method** : `GET`
+- **Path Parameter** :
+ - `countryname`: The name of the country you want to retrieve information for.
-**Content example**
-
-Request: `GET country/new%20zealand`
+**Example Request:**
+```http
+GET /country/new%20zealand
+```
+**Example Response:**
```json
[{
-"Code": "NZL",
-"Name": "New Zealand",
-"Continent": "Oceania",
-"Region": "Australia and New Zealand",
-"SurfaceArea": 270534,
-"IndepYear": 1907,
-"Population": 3862000,
-"LifeExpectancy": 77.8,
-"GNP": 54669,
-"GNPOld": 64960,
-"LocalName": "New Zealand/Aotearoa",
-"GovernmentForm": "Constitutional Monarchy",
-"HeadOfState": "Elisabeth II",
-"Capital": 3499,
-"Code2": "NZ"
+ "Code": "NZL",
+ "Name": "New Zealand",
+ "Continent": "Oceania",
+ "Region": "Australia and New Zealand",
+ "SurfaceArea": 270534,
+ "IndepYear": 1907,
+ "Population": 3862000,
+ "LifeExpectancy": 77.8,
+ "GNP": 54669,
+ "GNPOld": 64960,
+ "LocalName": "New Zealand/Aotearoa",
+ "GovernmentForm": "Constitutional Monarchy",
+ "HeadOfState": "Elisabeth II",
+ "Capital": 3499,
+ "Code2": "NZ"
}]
```
+### 3. Find the Total Population of a Continent
+Return the total population of a specified continent.
-### Find the total population of a continent
-
-Return a String with the number of the continent.
+- **URL** : `/population/:continent`
+- **Method** : `GET`
+- **Path Parameter** :
+ - `continent`: The name of the continent you want the population for.
-**URL** : `/population/:continent`
-
-**Method** : `GET`
-
-**Content example**
-
-Request: `GET country/new%20zealand`
-
-```string
-`The total population of asia is 3705025700`
+**Example Request:**
+```http
+GET /population/asia
```
+
+**Example Response:**
+```plaintext
+The total population of Asia is 3,705,025,700
+```
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 20297b8..52d6749 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -31,13 +31,21 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
+ "node_modules/aws-ssl-profiles": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.1.tgz",
+ "integrity": "sha512-+H+kuK34PfMaI9PNU/NSjBKL5hh/KDM9J72kwYeYEm0A8B1AC4fuCy3qsjnA7lxklgyXsB68yn8Z2xoZEjgwCQ==",
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
"node_modules/body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
+ "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"dependencies": {
"bytes": "3.1.2",
- "content-type": "~1.0.4",
+ "content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
@@ -45,7 +53,7 @@
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
- "raw-body": "2.5.1",
+ "raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
@@ -63,12 +71,18 @@
}
},
"node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+ "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -94,9 +108,9 @@
}
},
"node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"engines": {
"node": ">= 0.6"
}
@@ -114,6 +128,22 @@
"ms": "2.0.0"
}
},
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/denque": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
@@ -163,6 +193,25 @@
"node": ">= 0.8"
}
},
+ "node_modules/es-define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+ "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -177,16 +226,16 @@
}
},
"node_modules/express": {
- "version": "4.18.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
- "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
+ "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
- "body-parser": "1.20.1",
+ "body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.5.0",
+ "cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -251,9 +300,12 @@
}
},
"node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/generate-function": {
"version": "2.3.1",
@@ -264,34 +316,49 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
- "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+ "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
"has-proto": "^1.0.1",
- "has-symbols": "^1.0.3"
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"dependencies": {
- "function-bind": "^1.1.1"
+ "get-intrinsic": "^1.1.3"
},
- "engines": {
- "node": ">= 0.4.0"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"engines": {
"node": ">= 0.4"
},
@@ -310,6 +377,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -424,10 +502,11 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/mysql2": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.1.tgz",
- "integrity": "sha512-O7FXjLtNkjcMBpLURwkXIhyVbX9i4lq4nNRCykPNOXfceq94kJ0miagmTEGCZieuO8JtwtXaZ41U6KT4eF9y3g==",
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.0.tgz",
+ "integrity": "sha512-J9phbsXGvTOcRVPR95YedzVSxJecpW5A5+cQ57rhHIFXteTP10HCs+VBjS7DHIKfEaI1zQ5tlVrquCd64A6YvA==",
"dependencies": {
+ "aws-ssl-profiles": "^1.1.1",
"denque": "^2.1.0",
"generate-function": "^2.3.1",
"iconv-lite": "^0.6.3",
@@ -480,9 +559,12 @@
}
},
"node_modules/object-inspect": {
- "version": "1.12.3",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
- "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
+ "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -546,9 +628,9 @@
}
},
"node_modules/raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
@@ -630,19 +712,39 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"node_modules/side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+ "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dependencies": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
+ "object-inspect": "^1.13.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
diff --git a/server.js b/server.js
index a291b8f..5ef6c11 100644
--- a/server.js
+++ b/server.js
@@ -5,86 +5,98 @@ require("dotenv").config();
const app = express();
-//create a connection to the database using connection pools- this keeps the connection open and allows people to queue
+// Create a connection pool to the database
const pool = mysql.createPool({
- host: process.env.MYSQL_HOST, //localhost
- user: process.env.MYSQL_USER, //root user in mysql
- password: process.env.MYSQL_PASSWORD, //password for root user in mysql
- database: process.env.MYSQL_DATABASE, //name of the database you want to query
+ host: process.env.MYSQL_HOST,
+ user: process.env.MYSQL_USER,
+ password: process.env.MYSQL_PASSWORD,
+ database: process.env.MYSQL_DATABASE,
port: 3306,
- ssl:{ca:fs.readFileSync("./DigiCertGlobalRootCA.crt.pem")},
- waitForConnections: true, //if want to allow people to queue for connection spots
- connectionLimit: 10, // number of available connection spots
- queueLimit: 0, //how many people can queue for a connection spot- if 0 as many people as needed can queue
+ ssl: { ca: fs.readFileSync("./DigiCertGlobalRootCA.crt.pem") },
+ waitForConnections: true,
+ connectionLimit: 10,
+ queueLimit: 0,
});
//========== ENDPOINTS ============//
-//Root endpoint: return all countries
+
+// Root endpoint: returns all countries
app.get("/", (req, res) => {
- console.log("/ endpoint was hit 🎯");
- pool.query("SELECT * FROM country", (err, result) => {
- if (err) return console.log(err);
- res.send(result);
+ console.log("GET / endpoint was hit 🎯");
+ pool.query("SELECT * FROM country", (err, results) => {
+ if (err) {
+ console.error("Error fetching countries:", err);
+ return res.status(500).send("Internal Server Error");
+ }
+ res.json(results);
});
});
-
-//get a list of countries that belong in Oceania
+// Get a list of countries that belong to Oceania
app.get("/oceania", (req, res) => {
- console.log("/oceania endpoint was hit 🎯");
- pool.query(
- 'SELECT name, LifeExpectancy FROM country WHERE Continent = "Oceania" order by LifeExpectancy DESC LIMIT 10;',
- (err, result) => {
- if (err) return console.log(err);
- res.send(result);
+ console.log("GET /oceania endpoint was hit 🎯");
+ const query = `
+ SELECT Name, LifeExpectancy
+ FROM country
+ WHERE Continent = 'Oceania'
+ ORDER BY LifeExpectancy DESC
+ LIMIT 10;
+ `;
+ pool.query(query, (err, results) => {
+ if (err) {
+ console.error("Error fetching Oceania countries:", err);
+ return res.status(500).send("Internal Server Error");
}
- );
+ res.json(results);
+ });
});
-//Show the information about a specific country by it's name
+// Show information about a specific country by its name
app.get("/country/:countryname", (req, res) => {
- console.log("/country endpoint was hit 🎯");
- const countryname = req.params.countryname;
-
- pool.query(
- `SELECT * FROM country WHERE Name = "${countryname}";`,
- (err, result) => {
- if (err) return console.log(err);
- res.send(result);
+ console.log(`GET /country/${req.params.countryname} endpoint was hit 🎯`);
+ const { countryname } = req.params;
+
+ const query = "SELECT * FROM country WHERE Name = ?";
+ pool.execute(query, [countryname], (err, results) => {
+ if (err) {
+ console.error(`Error fetching details for ${countryname}:`, err);
+ return res.status(500).send("Internal Server Error");
}
- );
+ res.json(results);
+ });
});
-
-//Find the total population of a continent
+// Find the total population of a continent
app.get("/population/:continent", (req, res) => {
- console.log("/population/:continent endpoint was hit 🎯");
- const continent = req.params.continent;
- const query =
- "SELECT SUM(population)AS sum FROM country WHERE continent = ?;";
-
- pool.execute(query, [continent], (err, result) => {
- if (err) return console.log(err);
-
- console.log(result);
-
- res.send(`The total population of ${continent} is ${result[0].sum}`);
+ console.log(`GET /population/${req.params.continent} endpoint was hit 🎯`);
+ const { continent } = req.params;
+
+ const query = "SELECT SUM(Population) AS total_population FROM country WHERE Continent = ?";
+ pool.execute(query, [continent], (err, results) => {
+ if (err) {
+ console.error(`Error fetching population for ${continent}:`, err);
+ return res.status(500).send("Internal Server Error");
+ }
+ const totalPopulation = results[0]?.total_population;
+ res.send(`The total population of ${continent} is ${totalPopulation}`);
});
});
-
-
//========== PORT ============//
-const PORT = process.env.PORT;
-
-app
- .listen(PORT, () => {
- console.log(`Server is live at http://localhost:${PORT}`);
- })
- .on("error", (error) => {
- if (error.code === "EADDRINUSE") {
- console.log("Port is already in use");
- } else {
- console.log("Server Error", error);
- }
- });
+/**
+ App Service sets the environment variable PORT in the Node.js container,
+ and forwards the incoming requests to your container at that port number.
+
+ To receive the requests, your app should listen to that port using process.env.PORT.
+ */
+const PORT = process.env.PORT || 4000;
+
+app.listen(PORT, () => {
+ console.log(`Server is live at http://localhost:${PORT}`);
+}).on("error", (error) => {
+ if (error.code === "EADDRINUSE") {
+ console.error("Port is already in use");
+ } else {
+ console.error("Server Error:", error);
+ }
+});