The goal of this activity is to leverage our collective FE and BE knowledge to explain how this application works. At the end of this activity you should have a diagram that illustrates how information flows between FE and BE, and a deeper understanding of how to mitigate CORS issues in a service-oriented environment.
- Understand how information flows between the FE and BE
- Understand common misconceptions and pain points experienced by FE and BE devs
- What security vulnerabilities have we learned about so far?
- What's the difference between a
fetch
call in JS and a regular GET request?
Ruby version: 3.2.2
Rails version: 7.1.3
Node version: 16.14.2
npm version: 8.5.0
Clone this repo and cd
into it.
NOTE: For ease of setup, this Rails app is using a SQLite database instead of PostgreSQL. This won't affect anything else, but you may be curious about it!
- Navigate to the be directory:
cd be
- Install dependencies:
bundle install
- If you get an error that Bundler is not installed, install it with
gem install bundler
- If you get an error that Bundler is not installed, install it with
- Set up the database:
rails db:{drop,create,migrate,seed}
- run the server with
rails server
After you run the server you should see that it is waiting for requests. You can also navigate to http://localhost:3001/api/v1/welcome to simulate a request to your running server. Then, continue on with the FE setup steps below.
In a different terminal window,
- Navigate to the fe directory:
cd fe
- Install dependencies:
npm install
- Run the app:
npm start
- visit
localhost:3000
in your browser
If everything is set up properly you should see a friendly welcome message.
If everything isn't set up correctly, you may see a message that starts with "ERROR"... Your first task will be to solve this error.
- On the front end, look at DevTools' Console. Are there any errors present? What are they?
- On the backend,check your server logs in terminal. Are there any errors present? What are they?
CORS stands for Cross-Origin Resource Sharing
. Read more about it here, or you can search for more topics on your own.
- ❓ Think Break: Remember when we talked about the difference between the JavaScript
fetch()
method and regular ol' GET request?
In a nutshell, CORS is a rule that says a FETCH
request is different from a normal GET
request, and servers (or BE applications) should govern which origins (or applications that make FETCH requests) it will send responses to. To do this, the BE application can set a header for every request. That header would look like:
"Access-Control-Allow-Origin": "*"
... but, the above header would allow every origin (or domain) on the internet to access the responses generated by our application. Does that sound secure to you? 🤔
Rather than allowing all, let's specify which domain is allowed access to a response from our app. Follow these instructions together:
- Open the
be/app/controllers/api/v1/welcome_controller.rb
file and look at line 13. This line is commented out. - Uncomment it, and restart your rails server (
CTRL + C
in Terminal andrails s
again). Does the request work now?
This approach can work, but is not a conventional way to solve this problem in Rails. It would also mean we'd have to have this header present on any controller, or any action in each controller, which can quickly get out of hand.
Let's try a more sustainable approach:
- Re-comment out line 13.
- Find
be/config/initializers/cors.rb
. Read this file's instructions and the linked documentation. (By the way, this file was generated by Rails!) - Uncomment lines 8-16, changing
"example.com"
to the origin of your front-end (for our example, that's"localhost:3000"
), and restart your app. Try the request again. Does the request still work?
Ask these questions out loud, and share answers. Ask your partner to help define any technical terms you are unfamiliar with.
- ❓ What was line 13 in our controller actually doing?
- ❓ What is a Header?
- ❓ In your own words, what is CORS?
In small groups, designate one person to be the screen sharer. Answer the following questions together:
- Explain to the group what happens when you visit
localhost:3000
in your browser. Start withindex.html
and move toindex.js
. From there, trace all the way through the code up to the point where a request to the BE is made. - Explain to the group what happens when your Rails app receives a request. Trace all the way through the code up to the point that a response is sent back to the FE.
- Explain what happens once the FE app receives the response.
- Once you are finished exploring the code, draw a diagram that illustrates the entire process. Specify which parts are FE and which are BE.
Now that you know how each part of the application handles their request/response cycles, how would you collaborate as a combined team to consume a new set of data?
In both applications, implement the ability to list all the messages from the BE's database on a new FE page. Follow these steps:
-
Determine what data will be consumed/exposed via API. (For this exercise, we recommend all the
messages
on anindex
page - you may want to add more to theseeds.rb
file.) -
Write a user story.
Example:As a user, when I visit the messages index page (/messages) Then I see a list of all the messages in the system as links And when I click on one of the messages, I am taken to that message's show page (/messages/:id) where I only see that message.
-
Agree on a JSON contract for any requests & their responses required to fulfill the user story.
Example:REQUEST: GET /messages - No request body - No additional headers or keys required RESPONSE: - JSON format { data: { "type": "message", "id": "1", "attributes": { "text": "Here is a message!" } } }
- What are some tools you can use to ensure each person understands the requirements of a given project?
- Are there any technical vocab words that you don't understand? If so, try to help each other understand the meaning of those words.
- How could you get the app to display one of the other messages found in
seeds.rb
? - What are frustrations that BE developers might experience when working with FE developers that might work on a different team (for example, building an API/database based on specific requests from the FE team)?
- What are frustrations that FE developers might experience when using technology built by BE developers (for example, accessing an API)?