{"id":14967592,"url":"https://github.com/willsams/example-mvc-expressjs-with-python","last_synced_at":"2026-01-29T09:41:14.794Z","repository":{"id":216729464,"uuid":"742148787","full_name":"WillSams/example-mvc-expressjs-with-python","owner":"WillSams","description":"JavaScript + Python full stack example application using Express.js + Pug templating for the frontend and a GraphQL API backend using FastAPI. ","archived":false,"fork":false,"pushed_at":"2024-05-20T02:58:20.000Z","size":3123,"stargazers_count":0,"open_issues_count":16,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-10T09:46:02.952Z","etag":null,"topics":["ariadne","asyncpg","bootstrap4","direnv","docker","expressjs","fastapi","graphql","jquery","jwt-authorization","knexjs","mvc-architecture","nodejs","nvm","postgresql","pugjs","pytest","pytest-mock","python","sass"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WillSams.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"samswebs"}},"created_at":"2024-01-11T21:25:37.000Z","updated_at":"2024-02-14T11:44:28.000Z","dependencies_parsed_at":"2024-02-18T21:27:40.412Z","dependency_job_id":"cef6a47b-4f05-4bd5-b635-dd375262caf5","html_url":"https://github.com/WillSams/example-mvc-expressjs-with-python","commit_stats":null,"previous_names":["willsams/acme-hotel-express-fastapi-sqlalchemy","willsams/example-mvc-expressjs-with-python"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/WillSams/example-mvc-expressjs-with-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-mvc-expressjs-with-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-mvc-expressjs-with-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-mvc-expressjs-with-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-mvc-expressjs-with-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WillSams","download_url":"https://codeload.github.com/WillSams/example-mvc-expressjs-with-python/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WillSams%2Fexample-mvc-expressjs-with-python/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259864009,"owners_count":22923662,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ariadne","asyncpg","bootstrap4","direnv","docker","expressjs","fastapi","graphql","jquery","jwt-authorization","knexjs","mvc-architecture","nodejs","nvm","postgresql","pugjs","pytest","pytest-mock","python","sass"],"created_at":"2024-09-24T13:38:19.684Z","updated_at":"2026-01-29T09:41:14.754Z","avatar_url":"https://github.com/WillSams.png","language":"JavaScript","readme":"# Hotel Reservation MVC Example - JavaScript/Python\n\n**JavaScript, Expressjs, MVC frontend, Memcached, Python, FastAPI, GraphQL, AsyncPG, Postgres**\n[![Validate application](https://github.com/WillSams/example-mvc-expressjs-with-python/actions/workflows/pr-validate.yml/badge.svg)](https://github.com/WillSams/example-mvc-expressjs-with-python/actions/workflows/pr-validate.yml)\n\nThis example contains a frontend and backend:\n\n- The frontend is an [Express](https://expressjs.com/) application using an MVC architecture and [Pug](https://pugjs.org/api/getting-started.html) + [Bootstrap4](https://getbootstrap.com/docs/4.6/getting-started/introduction/) for view templating.\n- The backend is a [GraphQL API](https://graphql.org) providing the ability to create, delete, and list reservatios plus available rooms for a given date range.\n\nReact [Javascript](https://github.com/WillSams/example-js-react-with-python) and  [Typescript](https://github.com/WillSams/example-ts-react-with-python) versions of this same idea are available.\n\nBooked reservations are listed via the API. Each reservation request were processed in the order provided as if they were real-time requests. The following rules are observed:\n\n**Context**:\n\n* When a room is reserved, it cannot be reserved by another guest on overlapping dates.\n* Whenever there are multiple available rooms for a request, the room with the lower final price is assigned.\n* Whenever a request is made for a single room, a double bed room may be assigned (if no single is available?).\n* Smokers are not placed in non-smoking rooms.\n* Non-smokers are not placed in allowed smoking rooms.\n* Final price for reservations are determined by daily price * num of days requested, plus the cleaning fee.\n\n**Web UI Usage**:\n\n![text](./frontend/src/public/img/home_example.png) ![text](./frontend/src/public/img/new_example.png)\n\n**API Usage**:\n\nExample usage via [curl](https://curl.se/download.html):\n\n```bash\n# First, grab an access token provided by the API\nACCESS_TOKEN=$(curl -s -X POST \\\n  -H 'accept: application/json' \\\n  -H 'Content-Type: application/x-www-form-urlencoded' \\\n  -d 'grant_type=password\u0026username=example-user\u0026password=example-user' \\\n  'http://localhost:8080/token' | jq -r '.access_token')\n\n# List all existing booked reservations\ncurl http://localhost:$API_PORT/development/graphql \\\n    -H 'Content-Type: application/json' \\\n    -H \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n    -d '{\"query\": \"query { getAllReservations { reservations { room_id checkin_date checkout_date  } } }\"}'\n\n# Create a new reservation\n# Note: if there is an overlap, you'll see a \n#   'Reservation dates overlap with an existing reservation' error message\n# To see the aforementioned error, run this mutation a multiple times\ncurl http://localhost:$API_PORT/development/graphql \\\n    -H 'Content-Type: application/json' \\\n    -H \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n    -d '{ \"query\": \"mutation { createReservation( input: { room_id: \\\"91754a14-4885-4200-a052-e4042431ffb8\\\", checkin_date: \\\"2023-12-31\\\", checkout_date: \\\"2024-01-02\\\"  }) { success errors reservation { id room_id checkin_date checkout_date total_charge } } }\" }'\n\n# List Available Rooms for a given date range\ncurl http://localhost:$API_PORT/development/graphql \\\n    -H 'Content-Type: application/json' \\\n    -H \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n    -d '{\"query\": \"query { getAvailableRooms( input: { checkin_date: \\\"2023-12-31\\\", checkout_date: \\\"2024-01-02\\\" }) { success errors rooms { id num_beds allow_smoking daily_rate cleaning_fee } } }\" }'\n```\n\n**Open API UI Usage**:\n\nNavigate to [http://localhost:$API_PORT/docs](http://localhost:$API_PORT/docs).\n\n![text](./frontend/src/public/img/openapi_example.png)\n\n**Table of Contents**:\n\n* [Prerequisites](#prerequisites)\n* [Getting Started](#getting-started)\n    - [Install Python Packages](#install-python-packages)\n    - [Install Node.js Packages](#install-nodejs-packages)\n    - [Create the Database](#create-the-database)\n* [Development](#development)\n* [Testing](#testing)\n* [TODO](#todo)\n* [License](#license)\n\n## Prerequisites\n\nTo run the service, you will need to install the following tools.\n\n* [Python](https://www.python.org/downloads/)\n* [NodeJS](https://nodejs.org/en/)\n* [Docker](https://www.docker.com/)\n\nThe below are optional but highly recommended:\n\n* [nvm](https://github.com/nvm-sh/nvm) - Used to manage NodeJS versions.\n* [Direnv](https://direnv.net/) - Used to manage environment variables.\n\n## Getting Started\n\nFirst, we'll need to set up our environment variables.  You can do this by either any of the methods mentioned in [/tools/ENV.md](./tools/ENV.md) but I recommend using [Direnv](https://direnv.net/).\n\n### Install Python Packages\n\nNext, execute the following in your terminal:\n\n```bash\npython -m venv venv\nsource venv/bin/activate\npip install --upgrade pip \npip install -r requirements.txt\n```\n\n### Install Node.js Packages\n\nExecute the following within your terminal:\n\n```bash\nnvm use             # To eliminate any issues, install/use the version listed in .nvmrc. \nnpm i               # install the packages needed for project \n```\n\n### Create the database\n\nFinally, let's create and seed the database and our Reservations and Rooms tables:\n\n```bash\n# Create the database and seed it\nNODE_ENV=development | npm run refresh \u0026\u0026 npm run seed\n```\n\nDuring development, you can just execute `npm run dev:db-baseline` to refresh the database back to the original seed data.\n\n## Development\n\nTo run both the frontend and backend concurrently:\n\n```bash\ndocker-compose up -d  # runs the database in the background\nnpm run dev\n```\n\nAlso, you just execute the backend via `npm run dev:backend`.  to verify the backend is working:\n\n```bash\ncurl http://localhost:$API_PORT/$ENV/about\n```\n\nYou can also acces the Ariadne GraphiQL (interactive test playground) instance at [http://localhost:$API_PORT/$ENV/graphql](http://localhost:$PLAYGROUND_PORT/$ENV/graphql).  \n\n## Testing\n\nThe frontend utilizes [Jest](https://jestjs.io/).  To run these tests, simply execute `npm run test:frontend`.\n\n![text](./frontend/src/public/img/frontend_tests_example.png) \n\nThe backend tests organized for improved readability and comprehension. These tests are segmented into individual files, a structure that simplifies the testing process and enhances accessibility. While individual preferences may vary, this is my chosen approach for managing tests in this project.\n\nTo run these tests, simply execute `npm run test:backend`.\n\n![text](./frontend/src/public/img/backend_tests_example.png)\n\n## Containerization\n\n### Building the Backend Container\n\n```bash\ndocker build backend/. -t acme-hotel-example-backend:latest \\\n    --build-arg RESERVATION_PORT=\"80\" \\\n    --build-arg ENV=\"${ENV}\" \\\n    --build-arg IS_DEBUG=\"${IS_DEBUG}\" \\\n    --build-arg SECRET_KEY=\"$SECRET_KEY\" \\\n    --build-arg REFRESH_SECRET_KEY=\"$REFRESH_SECRET_KEY\" \\\n    --build-arg PG_URL=\"$PG_URL\"\n\n# finally, to run a named container\ndocker run --name backend-dev -p 8000:80 acme-hotel-example-backend`\n```\n\nTo verify the environment variables set, you can execute the following on the named container by:\n\n```bash\nCONTAINER_ID=$(docker ps -qf \"name=backend-dev\" -n 1)\n\n# this will display the container's environment variables in console\ndocker exec $CONTAINER_ID printenv   \n```\n\nIf you need to re-create the container with the same name, do **docker rm \u003ccontainer-name\u003e** (i.e., backend-dev) first.\n\n## License\n\nLicense information can be found [here](./LICENSE)\n\n","funding_links":["https://ko-fi.com/samswebs"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillsams%2Fexample-mvc-expressjs-with-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillsams%2Fexample-mvc-expressjs-with-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillsams%2Fexample-mvc-expressjs-with-python/lists"}