We will use the Ruby on Rails backend of Dev.to as Admin panel and create a custom frontend as Vue.js for our website.
End result
Introduction
I am very passionate about Algorithms and Open-source technologies. I have been writing stories about how to solve Leetcode problems. While I like the interface of Medium and Dev to write, but I feel they lack certain features like
Integrating an online code compiler with the story
Creating custom tags, like BFS, DFS, Stack, Queue
Marking progress of users
Better organization of articles, like coursera or Udemy.
So I decided to create my own open-source website which will have the following features:-
I will use the code base of Dev for my admin panel, to write stories
Create a Vue.js front-end for my website
Host it in Google cloud
Creating a subscription-based feature for the premium articles, 1:1 tutoring.
Architecture
The dev.to website uses Forem. Forem is open source software for building communities. The GitHub code which power Dev can be found here.
Puma as the webserver
Ruby on Rails as backend
PostgreSQL as the primary database
Redis* to store cached data
Sidekiq and Active Job for background workers
Elasticsearch* for in app searching
I thought it will be also a good opportunity to learn the best practice of caching
, authentication
, background jobs
Problem with the Forem codebase
The backend and front-end are tightly coupled. So, if I want to create a mobile app later, it will be a problem.
Monolithic code, which will be hard to maintain, unlike micro-services architecture.
Anyway, I am only concerned about the first problem right now, so the first goal is to create APIs which my front end can use. We will discuss how to create the frontend in the next tutorial in this series.
Watch It
If you want to watch this tutorial instead of reading it, you can watch it here. This video also explains the frontend part which will be discussed in the next tutorial in this series.
Backend (Admin Panel)
My first goal is to install the backend on google cloud, create some posts and make an API to list all the posts so that my Vue,js frontend can display those.
It was a bit challenging to run and deploy it but once I did it, I see it running in google cloud.
Now, the next goal is to make a new controller that can list all the articles and the meta-data associated with those articles in JSON format.
First of all, I created a route called /all . I intend to use this route to return the list of articles in a JSON format. Then, I create a SimplecodingArticlesController which was a sub-class of Devise::RegistrationsController, because I wanted to use require_no_authentication method, so that I can show those articles without any authentication as of now. Later I will use an access token to authenticate the APIs. Right now, a quick and dirty way is enough to get started.
Enabling CORS
As we mentioned earlier, we would use Forem as our backend and create a frontend in vuejs which would be hosted separately from the backend.
When this frontend will make requests to the Forem backend, these requests would be cross-origin requests as the frontend and the backend are separately hosted. Hence, to make the web browsers allow these cross-origin requests from our frontend, we will have to enable CORS from our backend.
To do this, we just need to add the following code in /config/initializers/cors.rb where the directory config is located in the root folder of Forem’s Github repo.
API for fetching all the articles of a tag
Now, I wanted to create an API for fetching all the articles that are associated with a single tag. This is very simple. I just had to create a route and a new method inside the simplecodingarticlescontroller class.
Modify the route.rb file as shown below
Create a new method in simplecoding_articles_controller.rb
Make sure to allow CORS on this route by modifying the /config/initializers/cors.rb file as shown in the Enabling CORS section
The JSON response of this api is same as shown for /all API
API for fetching a particular article
The API which we created earlier, sends the list of all the articles. Suppose, we need only a particular article. In that case, we will have to get all the articles from the API and then search for that particular article. This is inefficient. Let’s create an API that would return only a specific article.
Let’s create a new route /articles/:id in routes.rb as shown below.
Let us also create a new method inside the simplecoding_articles_controller.rb
The JSON response of this API looks like the following
Remember to enable CORS for this route as well
API for fetching Articles via Slugs
Currently, we have an API to fetch a single article using the id of the article. Let’s add another API that would enable us to fetch a single article using its slug.
Create a new route in routes.rb
Create a new method in simplecoding_articles_controller.rb
The response of this API is similar to that of the previous API.
Also, remember to enable CORS for this API as well.
GoodBye!
In the next tutorials, we will use these APIs for the front-end and also make API to fetch articles that belong to one tag.
Complete backend code can be found here
webtutsplus / simple-coding-rails
copy of forem
Forem 🌱
For Empowering Community
Welcome to the Forem codebase, the platform that powers dev.to. We are so excited to have you. With your help, we can build out Forem’s usability, scalability, and stability to better serve our communities.
What is Forem?
Forem is open source software for building communities. Communities for your peers, customers, fanbases, families, friends, and any other time and space where people need to come together to be part of a collective See our announcement post for a high-level overview of what Forem is.
dev.to (or just DEV) is hosted by Forem. It is a community of software developers who write articles, take part in discussions, and build their professional profiles. We value supportive and constructive dialogue in the pursuit of great code and career growth for all members. The ecosystem spans from beginner to advanced developers, and all are welcome to find their place…
Top comments (0)