by Bryant Cabrera
[TOC]
This is an API created for a fictitious Education Program.
Link to Front-End Repo: https://github.com/BryantCabrera/education-program-app
Link to Back-End Repo: https://github.com/BryantCabrera/education-program-api
Link to Deployed Project: https://education-program-app.herokuapp.com/
- Aggregates all data for every program into a convenient, easily accessible API.
- Converts data from .csv to data stored on MongoDB (mlab).
- Allows for CRUD operations on data.
- Not meant to manipulate data.
- Not meant to make calls to other APIs.
This project was built using 2 repos: 1 for the back-end and 1 for the front-end. Both projects incorporate similar eslint, prettier, and typescript scaffolding. The back-end implements RESTful routing, CRUD operations, and connects to a MongoDB (mlab). The front-end implements hot reloading, live typescript reloading, and server rendering out of the box.
NextJS -> React Front-End -> Node/Express server -> mongoDB ->
- React - Javascript Framework
- Styled Components - Styling
- NextJS - Server Side Rendering
- Node/Express - API
- Typescript - Type enforcement
- Prettier - Code formatting
- Jest Delightful JavaScript Testing
- React Testing Library Testing APIs for working with React components
tsconfig.json
provides higher level typescript configurationtslint.json
specifies linting rules- interfaces that may be used in multiple places are kept in the
/common/interfaces.ts
directory. - interfaces used in only one place can be defined where they are used (for example, React component props)
- run
npm run format
to format code. - code formatting is run automatically on
git commit
. Errors must be fixed before the commit can go through. - linting is managed with a combination of prettier and tslint
- prettier settings can be updated in the script in package.json
If you turn off JavaScript in your browser, then start the app in production mode and direct your browser to localhost:3000
, you'll see that the app renders with all its styles. That's because of the server render functionality. Server rendering can shorten the time to load, and also improve SEO.
If you want to add data fetched from an API to the server render, one way to do that is to use fetch from isomorphic unfetch and await
the result. This is because in NextJS, the react components don't have access to the server's fetch capabilities.
Server Documentation: View Documentation on swagger.io Placeholder
$npm install --save-dev nyc
- Make sure you have these scripts:
"test": "jest --coverage"
"coverage": "nyc report --reporter=html"
- In your jest.config.json file, make sure you have the following properties:
coverageDirectory: "coverage",
coverageReporters: ["text", "html"],
collectCoverageFrom: [
'**/*.{ts,tsx}',
'!**/node_modules/**',
'!**/build/**',
'!**/dist/**',
'!**/*.d.ts',
],
Run: npm install
Run: npm test
We have the option of running in either development mode or production mode.
Run: npm run dev
(build happens automatically)
- Frontend has hot reloading, backend rebuilds and restarts automatically when .ts files are updated.
To start, run: npm run start
.
To build and start run: npm run build:start
- Development mode: direct your browser to
localhost:3000
. The API runs onlocalhost:4000
. - To view live production app browse to https://education-program-app.herokuapp.com/
Alternate Method: Use Heroku CLI
-
Make sure your code is set up
-
Back-End
- Make sure your CORS settings in server.js whitelists the appropriate URLs that will be hitting the server
- Create a copy of your branch before you beging deploying master in case of any breaking changes
$git checkout -b master-copy-before-deployment
-
Front-End
-
Create a copy of your branch before you beging deploying master in case of any breaking changes
$git checkout -b master-copy-before-deployment
-
In package.json, make sure you have the following scripts "start": "node server.js", "build": "tsc -p .", "postinstall": "tsc -p .", "compile": "tsc && node server.js", "dev:server": "nodemon -e ts --exec "npm run compile""
-
$npm run build
-
-
-
$git add -A
$git commit -m "Prepares codebase for deployment."
$git push
-
$heroku create app-name
-
$git push heroku master
Current Method: CI (Continuous Integration) by linking Heroku to GitHub repo & branch
- Make sure your code is set up
- Back-End
- Make sure your CORS settings in server.js whitelists the appropriate URLs that will be hitting the server
- Create a copy of your branch before you beging deploying master in case of any breaking changes
$git checkout -b master-copy-before-deployment
- Front-End
- Create a copy of your branch before you beging deploying master in case of any breaking changes
$git checkout -b master-copy-before-deployment
- In package.json, make sure you have the following scripts "start": "node server.js", "build": "tsc -p .", "postinstall": "tsc -p .", "compile": "tsc && node server.js", "dev:server": "nodemon -e ts --exec "npm run compile""
$npm run build
- Create a copy of your branch before you beging deploying master in case of any breaking changes
- Back-End
$git add -A
$git commit -m "Prepares codebase for deployment."
$git push
$heroku create app-name
- Navigate to your heroku account > project name > deploy
- Connect your GitHub Account, enable auto-deployments, then select the branch to deploy from and trigger the 1st build
This service can deployed using docker. A Dockerfile is included which can be used to build it into a production grade docker image.
- If you don't already have it installed,
$brew install docker
- Build: from the root directory of this repo, run
docker build -t <registry>/<repo_name>:<tag> .
Push Docker Image To Registry (ONLY IF YOUR BUILD PIPELINE IS BROKEN)
- If the Docker image was built succesfully, log in to your registry in terminal.
- Example:
$az acr login --name bryant
and wait for it to print "Login Succeeded"
- Example:
- Push to registry:
docker push <registry>/<repo_name>:<tag>
. Example:$docker push example.io/educationprogram:latest
$docker run -p 8080:8080 <registry>/<repo_name>:<tag>
.$docker ps
shows what's running$docker kill xxxx
where xxxx are the 1st 4 characters of the docker image ID, kills the currently running docker image$docker image ls
shows a list of all Docker images
As a user, I want the app to open on a list of all programs.
As a user, I want to be able to sort the data in the table.
As a user, I want to be able to filter the data by typing into a search field and have it update as I type.
- Front-End
- React
- Jest + react-testing-library unit testing
- React
- Intermediary Server
- Jest + moxios unit tests
- Back-End
- Jest + supertest unit tests
- Create healthcheck path
- Bryant Cabrera
None present. Have yet to implement auth.
- Application is client-facing and deployed externally. While it does not touch personal information, it could have user information in the future.
- SOLUTION: The server should only be accessible if connecting with a whitelisted IP.
- There shouldn't be any command injection flaws.
- mongoDB
- 2 node/express servers
- react with NextJS SSR (server-side rendering)
- Assumptions
- There are only 111 documents in the mongoDB collection.
- We are the only ones currently posting to app. - Costs will be $0 for the time being.
- mlab for our MongoDB database.
- Versioning on GitHub for both back-end and front-end.
- If we choose to store historical data, mongoDB storage will grow exponentially as we progress. Costs might become prohibitive.
- Use POSTCss or Sass for styling.
- Utilize a monorepo structure.
TBD