Send JSON using RACK-CORS with Rails and use it in a JS Frontend
Category: tech
Updated: Mon at 19:31 on 29/04/2024 - published
Description: Things I wished I knew starting out as a beginner...
Cors was one of those unexpected things that tripped me up when I was starting out.
Hopefully this could help someone else save hours of time...
Context: rails backend exposing a json endpoint for a frontend app.
Hopefully this could help someone else save hours of time...
Context: rails backend exposing a json endpoint for a frontend app.
We will go through the steps needed to expose JSON mainly from the rails side, and then explain how you can retrieve the data from any JS front end. This assumes that you have some prior rails knowledge and that you already have an app in a repo with at least one model and one controller. If you are totally new to Rails, I recommend starting with the Odin Project or a bootcamp like Le Wagon, or resources like Go Rails and Pragmatic Studio.
With this article, I’m mainly thinking of people developing a classic Rails monolith, exposing JSON on a few endpoints publicly. Although this topic is still relevan within rails API only mode too. There are plenty of other ressources for setting up a 100% Rails API backend, if that’s what you are trying to do.
Once you have an app running, what we are trying to do is send some data stored in the database as json to whoever requested it. It’s important to understand that you can configure the end point to be usuable by all frontend apps, or only to certain front end apps with specified DNS.
If you try to use the endpoint in a website script and you haven’t declared the appropriate authorisations, you will get a CORS error on the client side. To fix this, you declare which DNS' can make the requests to your app. What we are doing is the more restricted version where we will declare who can access the json. Either way, we need the rack-cors gem.
1- in the gemfile, add
gem 'rack-cors'
2- run
bundle install
3- in the config/initializers a new cors.rb file should be there.
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'https://bikes4life.com'
resource '/my_json_function', headers: :any, methods: [:get]
end
endWhen you are developing, you might be developing your rails on localhost:3000 and have another server running locally for your front end, so be sure to use * to allow anyone to access the my_json_function including localhost:3001 (you are probably running your rails app on port 3000 and your js app on 3001), in development, it is ok to do this like so:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get]
end
endYou can make other declarations and add more methods, like update, post etc…
Restart your rails server after this.
Remember that when you push to production, you will have to change these URLs to point to the URLs you want to accept requests from. Again, if you want to allow everyone access, use * .
4- Then you should declare a route in your config/routes:
Rails.application.routes.draw do [...] get 'my_json_function', to: 'vehicules_controller#my_json_function' [...] end
5- Now its time to write the actual function that will do the hard work!
In your chosen controller, (in my case its a VehiculesController) we will send all the data from the bikes table in the DB. (this assumes that you have a Bike model).
def my_json_function @bikes= Bike.all render json: @bikes end
And that’s pretty much it on the rails side. Pretty cool!
You will probably want to do much more, like change the data:
def my_json_function
@vehicles = {}
@vehicles[:two_wheels] = Bike.all
@vehicles[:four_wheels] = Car.all
render json: @vehicles
endUsing jbuilder, would also be a good option if you want to do more with the json you send back.
6- Finally, fetch on the front end.
const fetchDataFunction = () => {
fetch('https://bikes4life.com/my_json_function')
.then((data)=> data.json())
.then((response) => console.log(response))
.catch((error) => console.log(error))
}From here, you will need to invoke the fetchDataFunction and probably add more functionality other than console.log.
As mentioned, this is a simplified run through but should be enough to guide ye novice in cors!
Thanks!
Thanks for reading.