Project 3
Run the application
To run the application you must first run npm install
in the root directory of the project.
You must also run cd backend
and then npm install
there as well. While you are in the
backend directory run npm start
, as the backend must run before the app can run.
You must then open a new terminal and run npm start
at the root directory of the project.
Then everything should work to check the project out, and it will open the app on localhost:3000
.
Project creation and choosing of components
We have created the project by using create-react-app. We have navbar and dropdown components to help with better design which match almost all types and sizes of screens. Article component fetches the articles data from database and display them with details. It gets the changes from Redux reducers and update the list of articles based on the query received from Redux reducers. Right now, we have no relations between search and filtering, this could be implemented in the future. Comment component take the input value of the comment and call the mutation to add it to right article. PgeButton change the page number by clicking on it. We choose to get 4 articles for each page. So if the amount of data is huge, we don't need to get all articles by one time.
Backend
Database
The following image shows how the MySQL database is set up.
The database is hosted on the VM by NTNU, at it2810-25.idi.ntnu.no:3306
, and to
and to get access to it you must be on the same network as it. That requires a VPN unless
you're on campus, but using VPN works wonders.
Backend Server
The backend is implemented in typescript, and is run with node after compilation to JavaScript. Full explanation of how to set up the server can be found in the README.
The file server.ts is compiled to the JS file which is the entry point. It uses the compiled output from schema.ts, which in turn uses the compiled output of db.ts.
The backend will start a server at localhost:8080
, and the GraphQL endpoint is at
localhost:8080/graphql
. Since this is a project where learning is the most important and
not that everything is extremely secure, we have decided to keep the GraphiQL available on
that endpoint. In a production environment this should be disabled, and that may be implemented
with an ENV_VARIABLE === "Dev"
or other variable for denoting development environment in
server.ts
GraphQL
The GraphQL schema was created programmatically with GraphQL types. The resolvers in the GraphQL Schema (that is the Root from which everything springs) were created in constants for Query and Mutation.
Both Query and Mutation have used argument lists extensively, as can be seen by
the args: {}
field on each field for either Query and Mutation. Some problems
were encountered with getting the resolvers to work well, as seen with article in
the const Query
in the schema.ts file. The same type
of query asking for the same kind of functionality was needed several places, so
the actual logic of it was moved to the function getArticlesFromDatabase(args: any)
,
which in turn got called at those two places. This did help to keep it DRY, and any
new features we might find we'd need would be easier to fix up for all places needing
that code.
Express
The backend server uses Express for the server, as it is a lot more lightweight than for example Apollo-server. Creating the backend with Apollo-server or any of the other packages touting themselves as being more high level might've made the development go faster, but we feel that using pretty low level packages which didn't bloat the application to extreme proportions did allow us to get a very good understanding of how the technologies work.
Sequalize
Sequalize was chosen as the ORM (Object Relational Mapping) language for this. This might have been a poor choice, as trying to work around how it worked was quite challenging and finding the functionality to do some of the queries we wanted took quite a lot of time, which might've been faster to just write proper SQL-queries for. But once we thought about that it was so much work to redo all we already had done with it that we let it be.
A little of the problem might've been in the fact that we created the database before trying to use Sequalize, which works, but most documentation and tutorials assume that you'll use Sequalize to create the database, which makes it harder to understand how to do things when that is not the case for us.
Test
npm install and npm start both frontend and backend parts first, then npm run e2e from prosjekt-3 to opens Cypress testing window. We have choosen to use Cypress for end-to-end testing. We have implemented som tests in cypress/integration/Search_test.tsx. The tests can run from Cypress window by clicking on the test file.
npm run test from prosjekt-3 to run normal test in react app.
Fetch from Graphql API
We have used the function fetch to get data from database. We had to add proxy information in package.json to be able to call the database port which is 8080 from our local port 3000. Filter types are hard coded right now, but we could fetch them too in the future.
State management API
We have used Redux API to make relations between the components. On Search, Filter, Sort and Change pages, we use Redux reducers and actions to make database queries based on type choosen, or to change the page to next page. We have used redux connect function to pass the selector and dispatch functions into class component props. In App.tsx and Navbar.tsx, we used useSelector function directly to pass changes into Article component.
User Login
We have implemented a Login-option for the user. The userdata is stored in the database and is fetched in the userLogin-component. We wanted to implement a registration, but for now use: Username: test and password: test. We also wanted to connect each comment to a userID, but we experienced some issues and lack of time to fix.
Save data
The user is able to add comments on articles by writing the comment and clicking on Add comment button. The comments will be saved in database. The webpage will be updated with the new changes and display all articles dynamically. So it's possible to see the added comment.