{"info":{"_postman_id":"1c083938-f2ef-4ae6-aad1-0c1986fd90be","name":"6 - Express Lets Start Building the Natours API","description":"<html><head></head><body><p>This collection was built as part of <strong>Section 6 – Express: Let's Start Building the Natours API</strong>, a hands-on module focused on learning the fundamentals of Express.js by constructing a real-world REST API.</p>\n<h3 id=\"whats-covered\">What's covered</h3>\n<p>The requests in this collection explore the core building blocks of an Express server and a tours-based API:</p>\n<ul>\n<li><p><strong>Basic Express responses</strong> – Sending plain text and JSON data from a local Express server (<code>127.0.0.1:3000</code>), demonstrating how Express handles different response types.</p>\n</li>\n<li><p><strong>POST request handling</strong> – Submitting message text to the local server to practice reading request bodies.</p>\n</li>\n<li><p><strong>Tours API (local)</strong> – Fetching all tours from the locally running Natours API (<code>/api/v1/tours</code>), mirroring the endpoint being built during the course.</p>\n</li>\n<li><p><strong>Tours API (production)</strong> – Querying the live Natours production server (<code>natours.dev</code>) to retrieve all tours and search for a specific tour by its ID.</p>\n</li>\n<li><p><strong>Authentication boundary</strong> – A deliberate failing request to the <code>/api/v1/users</code> endpoint to observe how protected routes behave.</p>\n</li>\n<li><p><strong>External API example</strong> – A call to the Dog CEO API to illustrate how Postman can interact with any third-party REST API.</p>\n</li>\n</ul>\n<h3 id=\"base-urls\">Base URLs</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Environment</th>\n<th>Base URL</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Local dev</td>\n<td><code>127.0.0.1:3000</code></td>\n</tr>\n<tr>\n<td>Production</td>\n<td><code>https://www.natours.dev/api/v1</code></td>\n</tr>\n</tbody>\n</table>\n</div></body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"45895052","collectionId":"1c083938-f2ef-4ae6-aad1-0c1986fd90be","publishedId":"2sBYB1N8gY","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"55c57a"},"publishDate":"2026-09-17T19:02:44.000Z"},"item":[{"name":"Get Dog Image","id":"838da933-bb7d-4cfc-a28b-51cb739e3151","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://dog.ceo/api/breeds/image/random","description":"<p>Fetches a random dog image URL from the <a href=\"https://dog.ceo/dog-api/\">Dog CEO API</a>.</p>\n<p><strong>Endpoint:</strong> <code>GET https://dog.ceo/api/breeds/image/random</code></p>\n<p><strong>Authentication:</strong> None required.</p>\n<p><strong>Response:</strong>\nReturns a JSON object with the following fields:</p>\n<ul>\n<li><code>message</code> <em>(string)</em>: A URL pointing to a random dog image.</li>\n<li><code>status</code> <em>(string)</em>: The status of the request (e.g., <code>\"success\"</code>).</li>\n</ul>\n<p><strong>Example Response:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"message\": \"https://images.dog.ceo/breeds/hound-afghan/n02088094_1003.jpg\",\n  \"status\": \"success\"\n}\n</code></pre>\n<p><strong>Notes:</strong></p>\n<ul>\n<li>The image URL changes with every request.</li>\n<li>No API key or authentication is needed.</li>\n<li>Part of the free, open <a href=\"https://dog.ceo/dog-api/\">Dog CEO REST API</a>.</li>\n</ul>\n","urlObject":{"protocol":"https","path":["api","breeds","image","random"],"host":["dog","ceo"],"query":[],"variable":[]}},"response":[],"_postman_id":"838da933-bb7d-4cfc-a28b-51cb739e3151"},{"name":"GET Plain Text","id":"a3974680-648a-405b-aeb1-ec574ab8ec9e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"127.0.0.1:3000","description":"<h2 id=\"get-plain-text\">GET Plain Text</h2>\n<p>Sends a simple <code>GET</code> request to the root endpoint of a local Node.js/Express development server and retrieves a <strong>plain text</strong> response.</p>\n<h3 id=\"endpoint-details\">Endpoint Details</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>GET</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>http://127.0.0.1:3000</code></td>\n</tr>\n<tr>\n<td><strong>Headers</strong></td>\n<td>None</td>\n</tr>\n<tr>\n<td><strong>Query Params</strong></td>\n<td>None</td>\n</tr>\n<tr>\n<td><strong>Request Body</strong></td>\n<td>None</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"description\">Description</h3>\n<p>This request targets the root (<code>/</code>) route of a locally running Express server on port <code>3000</code>. It expects the server to respond with a plain text message — typically used to verify that the server is up and running correctly.</p>\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>This request is intended for <strong>local development only</strong>. Ensure the Node.js/Express server is running on <code>127.0.0.1:3000</code> before sending.</li>\n<li>No authentication, headers, or body are required.</li>\n<li>The response content type is expected to be <code>text/plain</code>.</li>\n</ul>\n","urlObject":{"port":"3000","host":["127","0","0","1"],"query":[],"variable":[]}},"response":[],"_postman_id":"a3974680-648a-405b-aeb1-ec574ab8ec9e"},{"name":"POST Message Text","id":"56c98b50-9a62-4933-9708-33bec0ce8db9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"url":"127.0.0.1:3000","description":"<h2 id=\"post-message-text\">POST Message Text</h2>\n<p>Sends a <code>POST</code> request to the root endpoint of a local Node.js/Express development server to submit a plain text message body.</p>\n<h3 id=\"endpoint-details\">Endpoint Details</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>POST</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>http://127.0.0.1:3000</code></td>\n</tr>\n<tr>\n<td><strong>Headers</strong></td>\n<td>None</td>\n</tr>\n<tr>\n<td><strong>Query Params</strong></td>\n<td>None</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"description\">Description</h3>\n<p>This request targets the root (<code>/</code>) route of a locally running Express server on port <code>3000</code>. It is used during the course to practice handling <code>POST</code> requests in Express — specifically reading and processing a text message sent in the request body.</p>\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>This request is intended for <strong>local development only</strong>. Ensure the Node.js/Express server is running on <code>127.0.0.1:3000</code> before sending.</li>\n<li>No authentication or query parameters are required.</li>\n<li>Part of <strong>Section 6 – Express: Let's Start Building the Natours API</strong>.</li>\n</ul>\n","urlObject":{"port":"3000","host":["127","0","0","1"],"query":[],"variable":[]}},"response":[],"_postman_id":"56c98b50-9a62-4933-9708-33bec0ce8db9"},{"name":"GET JSON DATA","id":"47a7cd9f-e865-4fb4-9ae8-8691488ed4d1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"127.0.0.1:3000","description":"<p>Sends a <strong>GET</strong> request to the local development server running on <code>127.0.0.1:3000</code> and retrieves a JSON response.</p>\n<p>This request is used during local development and testing of the <strong>Natours API</strong>, built with Node.js and Express. It serves as a basic connectivity check to confirm the server is running and returning JSON data correctly.</p>\n<h3 id=\"details\">Details</h3>\n<ul>\n<li><strong>Method:</strong> GET</li>\n<li><strong>Base URL:</strong> <code>127.0.0.1:3000</code></li>\n<li><strong>Auth:</strong> None</li>\n<li><strong>Request Body:</strong> None</li>\n</ul>\n<h3 id=\"expected-response\">Expected Response</h3>\n<p>A JSON object or array returned by the Express server.</p>\n","urlObject":{"port":"3000","host":["127","0","0","1"],"query":[],"variable":[]}},"response":[],"_postman_id":"47a7cd9f-e865-4fb4-9ae8-8691488ed4d1"},{"name":"GET Natour Tour Data","id":"f21e9a9a-c0f7-49a5-ad66-2041526dda9c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://www.natours.dev/api/v1/tours","description":"<h2 id=\"get-all-tours\">GET All Tours</h2>\n<p>Retrieves a list of all available tours from the Natours API.</p>\n<h3 id=\"endpoint\">Endpoint</h3>\n<p><code>GET https://www.natours.dev/api/v1/tours</code></p>\n<h3 id=\"authentication\">Authentication</h3>\n<p>No authentication required.</p>\n<h3 id=\"request-parameters\">Request Parameters</h3>\n<p>No query parameters, path variables, or request body required.</p>\n<h3 id=\"response\">Response</h3>\n<p>Returns a JSON object containing:</p>\n<ul>\n<li><code>status</code> — <code>\"success\"</code> if the request was successful.</li>\n<li><code>results</code> — The number of tours returned.</li>\n<li><code>data.tours</code> — An array of tour objects, each containing details such as tour name, duration, difficulty, price, summary, and more.</li>\n</ul>\n<h3 id=\"example-response\">Example Response</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"results\": 9,\n  \"data\": {\n    \"tours\": [\n      {\n        \"name\": \"The Forest Hiker\",\n        \"duration\": 5,\n        \"difficulty\": \"easy\",\n        \"price\": 397,\n        \"summary\": \"Breathtaking hike through the Canadian Banff National Park\"\n      }\n    ]\n  }\n}\n</code></pre>\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>This endpoint returns all tours without any filtering or pagination by default.</li>\n</ul>\n","urlObject":{"protocol":"https","path":["api","v1","tours"],"host":["www","natours","dev"],"query":[],"variable":[]}},"response":[],"_postman_id":"f21e9a9a-c0f7-49a5-ad66-2041526dda9c"},{"name":"Search By ID","id":"90386737-cc06-4c4e-8382-a8c8057afd36","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://www.natours.dev/api/v1/tours/5c88fa8cf4afda39709c2955","description":"<h1 id=\"search-tour-by-id\">Search Tour By ID</h1>\n<p>Retrieves a <strong>single tour</strong> from the Natours API using its unique identifier. This endpoint returns the full tour object matching the provided ID.</p>\n<hr />\n<h2 id=\"endpoint\">Endpoint</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>URL</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>GET</code></td>\n<td><code>https://www.natours.dev/api/v1/tours/:id</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>✅ Yes</td>\n<td>The unique MongoDB ObjectID of the tour (e.g. <code>5c88fa8cf4afda39709c2955</code>)</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"example-request\">Example Request</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET https://www.natours.dev/api/v1/tours/5c88fa8cf4afda39709c2955\n</code></pre><hr />\n<h2 id=\"responses\">Responses</h2>\n<h3 id=\"✅-200-ok--tour-found\">✅ 200 OK — Tour Found</h3>\n<p>Returns the tour object matching the given ID.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"data\": {\n    \"tour\": {\n      \"_id\": \"5c88fa8cf4afda39709c2955\",\n      \"name\": \"The Forest Hiker\",\n      \"duration\": 5,\n      \"maxGroupSize\": 25,\n      \"difficulty\": \"easy\",\n      \"price\": 397,\n      ...\n    }\n  }\n}\n</code></pre>\n<h3 id=\"❌-404-not-found--tour-does-not-exist\">❌ 404 Not Found — Tour Does Not Exist</h3>\n<p>Returned when no tour matches the provided ID.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"fail\",\n  \"message\": \"No tour found with that ID\"\n}\n</code></pre>\n","urlObject":{"protocol":"https","path":["api","v1","tours","5c88fa8cf4afda39709c2955"],"host":["www","natours","dev"],"query":[],"variable":[]}},"response":[],"_postman_id":"90386737-cc06-4c4e-8382-a8c8057afd36"},{"name":"Fail To GET Loign Data","id":"583cac43-76f7-467d-ae4f-53bce923cfe3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://www.natours.dev/api/v1/users","description":"<h2 id=\"fail-to-get-login-data\">Fail To GET Login Data</h2>\n<p><strong>Method:</strong> <code>GET</code>\n<strong>Endpoint:</strong> <code>https://www.natours.dev/api/v1/users</code></p>\n<h3 id=\"overview\">Overview</h3>\n<p>This is a <strong>negative test case</strong> that intentionally attempts to retrieve login data by sending a <code>GET</code> request to the <code>/api/v1/users</code> endpoint. The request is expected to <strong>fail</strong>, as <code>GET</code> is not the correct HTTP method for authentication/login operations, and this endpoint does not support retrieving login data in this manner.</p>\n<h3 id=\"purpose\">Purpose</h3>\n<ul>\n<li>Validates that the API correctly rejects an improper use of the <code>GET</code> method for login.</li>\n<li>Ensures the endpoint does not inadvertently expose login or authentication data via a <code>GET</code> request.</li>\n</ul>\n<h3 id=\"expected-behavior\">Expected Behavior</h3>\n<p>The API should respond with an <strong>error status</strong> (e.g., <code>404 Not Found</code>, <code>405 Method Not Allowed</code>, or <code>400 Bad Request</code>), confirming that login data cannot be accessed through this endpoint and method combination.</p>\n","urlObject":{"protocol":"https","path":["api","v1","users"],"host":["www","natours","dev"],"query":[],"variable":[]}},"response":[],"_postman_id":"583cac43-76f7-467d-ae4f-53bce923cfe3"},{"name":"GET TOURS DATA","id":"92c93262-8f44-47cd-ae4e-4ba4cc0a6892","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"127.0.0.1:3000/api/v1/tours","description":"<h2 id=\"get-tours-data\">GET TOURS DATA</h2>\n<p>Retrieves a list of all available tours from the Natours API.</p>\n<h3 id=\"endpoint\">Endpoint</h3>\n<p><code>GET 127.0.0.1:3000/api/v1/tours</code></p>\n<h3 id=\"description\">Description</h3>\n<p>This endpoint returns all tour records stored in the Natours database. Use it to fetch the complete collection of tours, including details such as tour names, durations, prices, ratings, and other relevant tour information.</p>\n<h3 id=\"response\">Response</h3>\n<ul>\n<li><strong>200 OK</strong> – Successfully returns an array of all tour objects.</li>\n<li><strong>500 Internal Server Error</strong> – Something went wrong on the server side.</li>\n</ul>\n","urlObject":{"port":"3000","path":["api","v1","tours"],"host":["127","0","0","1"],"query":[],"variable":[]}},"response":[],"_postman_id":"92c93262-8f44-47cd-ae4e-4ba4cc0a6892"}]}