- Create a fork of this project
- Clone your fork into your local machine.
- Add an
upstream
remote pointing to the main CYF repo (to be able to pull updates from your team members)
After cloning the project, we will create the local database that the project will use.
- Open the terminal, and
cd
intoserver
- Create your database:
createdb final_project
npm run recreate-db:local
(this will create and populate your new team's DB with the data your colleague added)
Your actual database schema will go to
server/db/recreate-schema.sql
and you can add sample test data inserver/db/populate-db.sql
Now let us test that the whole stack works (the React frontend
connects to the Node API
which connects to the Postgres Database
)
- Open a terminal, navigate to the root of the project and do
npm install
cd
intoserver
and runnpm run dev
- On a different terminal,
cd
intoclient
and runnpm run dev
Once the React website opens in a browser. Navigate to the Status page, and you should see two users listed in the page. This means everything works fine.
Read the Development process.
IMPORTANT: Make sure you read and understand the development proces guidelines before starting any work. Ask mentors for explanation if you have any questions.
The project is divided into client
folder for the React frontend, and a server
folder for the node API and database side.
This structure is called a mono repo. As opposed to having two repos (one for client, another for server), we opted for a
monorepo
. You can read more about monorepos.
The client is a React app created with create-react-app. In addition to the default setup, we have added React Router with 3 routes for testing
-
The
components
live in thecomponents
folder. When the project gets bigger, we might separate them into logical folders (i.e.components/admin
for admin-related components, andcomponents/profile
for user profile-related components) -
The
api
folder contains modules to call a specific API, i.e. when you add a new endpoint to list, craete and update jobs then you can add a new module calledapi/jobs.js
that can contain methods such asgetJobs, createJob, deleteJob ...
. -
The tests live with the modules. Some projects put the tests in a top-level folder
__tests
but we chose that they live with the components they test, i.e. a test forAbout.js
will be in a file calledAbout.test.js
at the same level in the folder. -
Styles are in the folder
client/styles
. Each file in that folder will contain styles related to a specific component (and have the same name), i.e. a component calledAbout.js
might define styles instyles/About.css
and import them.
We will use Semantic UI component library for the projects. Check out the documentation to get familiar with it.
The API is implemented using Express framework. We have added some extra functionality, such as a simple authentication solution.
-
db
folder contains the script to run to create the database, the schema and seed it with sample data. Whenever you want to add a new database table or change an existing, you will likely change it indb/recreate-schema.sql
. -
services
folder containdatabase
services. These are modules to manipulate a certain entity in the database. For example, if you have a table calleddocuments
, you might add a moduleservices/database/documents
that will expose methods likeaddDocument, getDocumentById
and implement anSQL
statement to perform the required functionality. -
api
When you add a new API, for example for managingquestions
. You can add it atapi/index.js
. This will define the prefix so for example,
const questions = require('./questions');
router.use('/questions', questions);
and in questions
module you will define the routes. Note these will all be prefixed with questions.
For example
// questions.js
const express = require('express');
const router = express.Router();
// This route is GET /questions/ (because everything in this file is "mounted" on the prefix questions from the previous step)
router.get('/', (req, res) => {
res.send('All good')
});
module.exports = router;
This structure using Express.Router
allows our code to be modular and minimise conflict between team members. You can read more about Express Router
Typically a server-side user story will involve:
- Define a table in
db/recreate-schema.sql
- Create an API endpoint
api/some_table.js
- Create a service under
services/databases/some_table.js
(this will contain the SQL to connect the API and the database)
The project has routes and services to implement an authentication / authorisation solution. It depends on passportjs library, and implements an authentication strategy called JWT. To understand more authentication, you can read this article.
To test authentication:
-
In Postman, do a GET on
http://localhost:4000/api/status/protected
. You should receive a403
(Forbidden) as a response. -
Register a user by doing a POST to
http://localhost:4000/auth/register
with the body looking like:
{
"email": "[email protected]",
"password": "mypassword"
}
Don't forget to set the content-type
to raw
and application/json
- Now you can login by doing a POST to
http://localhost:4000/auth/login
with a body similar to:
{
"email": "[email protected]",
"password": "mypassword"
}
This will bring you back a token
. Copy the token you get in the response.
- Now, we can use this token for the
status/protected
route. Do a GET request tohttp://localhost:4000/api/status/protected
and add aheader
with the nameAuthorization
and the value:Bearer the_token_from_previous step
, i.e.Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjMsImlhdCI6MTU2NTkwOTU4OX0.qidn4r7nrolFByyfd956Kh8BkOhwcaUSzyUK0V7su1c