Skip to content

A request journey

SahilKalra98 edited this page Mar 23, 2022 · 22 revisions

Introduction

This document's goal is to help you understand the inner workings of the codebase by explaining what happens when a request is sent to https://c0d3.com.

Web app

Please start with the c0d3.com request, it is the most complete and has the most details. All subsequent request journeys are short high level descriptions

What happens when you type https://c0d3.com into your browser url bar and hit enter?

  1. When you type https://c0d3.com/ (notice how www is not in the url) in your browser and hit enter, DNS resolution will resolve to our Digital Ocean application server, the same one that hosts our curriculum's demo apps. The request will be sent there
    • Our application server's caprover application has an nginx redirection (if you login to caprover, the redirection application is called redirect-to-www) to send back a 301 HTTP response code for https://www.c0d3.com.
  2. Browser sends a request to https://www.c0d3.com (notice the www in the url). DNS resolution for this url will resolve to a server owned by Vercel, and the request will be sent to the vercel instance that hosts our application.
    • Take a look at our nextjs config. If a route is defined there, nextJS will immediately respond with those rules first.
    • For our example, vercel will send back HTML and assets from their CDN, which contains our landing page. Keep in mind, this page is static, which means during deployment the page is built and put into their CDN for faster response times.
  3. When browser receives the index page, the first code that runs is _app.tsx. This file is a container for every page.
  4. After running _app.tsx, the browser renders the index page component. The first thing it does is to try to predict user login status by checking localstorage.
    • This is done to have a faster loading page. Alternatives were to send request to check for login status (slow), or server side render (then we can't use cdn)
    • If user is not logged in, the landing page is rendered.
  5. Let's assume the user is logged in, in that case the curriculum page is rendered. Keep in mind we are using client side routing so this page change does not result the browser to send a new request to /curriculum.
    • /curriculum page has a getStaticProps, which means the page is getting server side generated (SSG) by vercel and then uploaded to their CDN every five minutes. More info with NextJS documentation.
      • We choose to do this because lesson content and challenges do not change often so it did not make sense for every user to send a request to fetch an additional request to get lesson and challenge descriptions on every page load. Instead, we build this page once every 5 minutes and push to the CDN so every user will get the lesson and challenge data along with the page.
    • Since _app.tsx already ran when loading the index page, it does not run again.
  6. As the curriculum page loads, a graphql request is sent to the server by calling useGetSessionQuery.
    • The useGetSessionQuery is autogenerated by graphql code generator by running yarn generate.
      • The reason why we use code generator is because it is tedious to write out our graphql front end queries and then write out the types (for typescript) for it. Codegen will take our queries and autogenerate hooks and typescript types.
    • This query request is sent to the server.
  7. When server receives the graphql query at /api/graphql, which is handled by /pages/api/graphql.ts
  8. The request continues to the session query resolver, which queries our database using prisma and returns the data to the browser.
    • We use prisma for our database queries so we don't have to write SQL and typescript types manually. For example, if we were to get the stars using SQL, it would look something like SELECT * FROM USERS WHERE .... INNER JOIN ... , which is complicated! Prisma allows us to query our database easily using JavaScript syntax and then generates optimized SQL for us along with types for typescript.
  9. The browser continues to render the curriculum page and renders LessonCard components for each lesson. For each card, if the user has passed a lesson a request would be sent to retrieve the submissions for the lesson.
  10. The request goes to /api/graphql (mentioned above) and makes its way to submissions resolver, where Prisma is used to query the submissions for the given lesson.

Done! Page is now completely loaded!

Sign In

  1. User clicks sign in on the client side
  2. The request eventually arrives at the graphql resolver, which either throws an error or sets the session cookie and returns the user information.
  3. When the client side receives the response, it sets the corresponding errors if there are errors. If not, the localStorage is updated and user redirected to /curriculum.

Sign Up

  1. User clicks sign up on the client side
  2. A request eventually arrives at the graphql resolver, which either throws an error or returns the user information.
  3. When the client side receives the response, it sets the corresponding errors if there are errors. If not, the user shown the signup success component.
  4. The signup success component prompts user to set their password.
  5. When the user types their password and hits submit, a request goes to graphql resolver, which would either throw error or sets the user cookie and returns a success message.
  6. Once successful, user is shown a success message with a button to continue to the curriculum page.

CLI

Keep in mind the CLI is in a different repo!

c0d3 login

What happens when you type c0d3 login into the terminal to login?

  1. You are prompted for your c0d3 credentials.
  2. A graphql request is sent to www.c0d3.com/api/graphql with a login mutation.
  3. The request goes through the middlewares first and then arrives at the login mutation.
  4. When cli receives the response, the token is written into ~/.c0d3/credentials.json

c0d3 submit

What happens when you type c0d3 submit into the terminal to submit your code?

  1. The CLI gets the token that is generated by the c0d3 login command, gets the diff between the current branch and master branch, prompts for lesson and challenge, and prompts for confirmation.
  2. The CLI sends a submission graphql request to www.c0d3.com/api/graphql with a create submission mutation.
  3. The request goes through the middlewares first and then arrives at the createSubmission mutation.
    • In the createSubmission mutation resolver, a new submission will be created, if there's a previous submission, its status will be updated to Overwritten.

Other Resolvers

This resolver deals with adding and removing alerts for every user. Alerts have two different categories which are info and urgent which can only be added and removed by an admin here.

  • addAlert deals with adding an alert so that when an alert is added, users can see that alert on their dashboard.

  • removeAlert deals with removing an alert so users won't be able to see it on the dashboard anymore.

This resolver handles with changing admin rights for users with changeAdminRights

This resolver handles with the login, signout, and signup of a user.

  • login - Handles with logging in a user and updating the session.
  • logout - Handles with logging out a user and destroying the session object.
  • signup - Handles with signing up a user/creating a user with prisma.
  • isTokenValid - Checks if CLI token is valid. Created because of issue highlighted here.

This resolver handles creating and updating a challenge on the admin page

  • createChallenge - Creates a new challenge for a lesson.
  • updateChallenge - Updates an existing challenge for a lesson.

This resolver handles creating and updating a lesson on the admin page

  • createLesson - Creates a new lesson with its respective content.
  • updateLesson - Updates an existing lesson and its content.

This resolver deals with requesting and changing a user's password on the forgot password page

  • reqPwReset - Handles sending an email to a user requesting a password change.
  • changePw - Handles with changing a user's password and updating it.

This resolver handles the action of giving a star to a user. When a star is given, a message is also sent to the according Discord channel, notifying who gave a star and who had received a star.

  • setStar - handles giving a star to a user and sending a message to the correct discord channel.

This resolver handles retrieving user information to be displayed on the profile page

  • userInfo - returns user information such as username, stars received and given, etc.