How I Used the Opensource Codebase of Dev Community to Build My Own Website
Tags: forem, opensource, backend, rails
Published: 2021-02-26 14:27:25


![](https://cdn-images-1.medium.com/max/2400/1*4DvdfTyTJsP10bST3HPsAA.png)



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**

[https://www.simplecoding.dev/](https://www.simplecoding.dev/)

![](https://cdn-images-1.medium.com/max/5760/1*6a5jAUVsrqQoCbED3cUHyw.png)

![](https://cdn-images-1.medium.com/max/5652/1*LPD1vddWbT12iFcqyqUwSA.png)

![](https://cdn-images-1.medium.com/max/5572/1*qiMF5_49B1PxbvxoQMEVZg.png)

![](https://cdn-images-1.medium.com/max/5760/1*vzEc3-fvh80SSUYSEON4mg.png)

## 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](http://dev.to) to write, but I feel they lack certain features like

 1. Integrating an online code compiler with the story

 2. Creating custom tags, like BFS, DFS, Stack, Queue

 3. Marking progress of users

 4. Better organization of articles, like coursera or Udemy.

So I decided to create my own open-source website which will have the following features:-

 1. I will use the code base of Dev for my admin panel, to write stories

 2. Create a Vue.js front-end for my website

 3. Host it in Google cloud

 4. Creating a subscription-based feature for the premium articles, 1:1 tutoring.

## Architecture

The [dev.to](https://dev.to/) website uses Forem. Forem is open source software for building communities. The GitHub code which power [Dev](http://dev.to) can be found [here](https://github.com/forem/forem).

[Forem’s stack consist of](https://docs.forem.com/technical-overview/stack/)

* [Puma](https://github.com/puma/puma) as the webserver

* Ruby on Rails as backend

* [PostgreSQL](https://www.postgresql.org/) as the primary database

* [Redis](https://redis.io/)* to store cached data

* [Sidekiq](https://github.com/mperham/sidekiq) and [Active Job](https://guides.rubyonrails.org/active_job_basics.html) for background workers

* [Elasticsearch](https://www.elastic.co/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](https://medium.com/p/fa3b9f262f2/edit) 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.
{% youtube mlUZLlGaSSs %}
## 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.

![Homepage](https://cdn-images-1.medium.com/max/2716/1*nFEEcu13hO9Mi9JVMGkw-g.png)

![Admin page](https://cdn-images-1.medium.com/max/2720/1*AXHbui8pTpg6j5b1YhpvOg.png)

![Articles](https://cdn-images-1.medium.com/max/2712/1*XuTwz0PDYlgEd6lCphNAOw.png)

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.
{% gist https://gist.github.com/shivamag00/fefeb84921abbcb593655b12ba144789.js %}
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.
{% gist https://gist.github.com/nilmadhab/7669742fe4c4b92ae2696e55122d64ec.js %}{% gist https://gist.github.com/nilmadhab/4643950d97670b5da9bea757e3986254.js %}
## 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.
{% gist https://gist.github.com/shivamag00/4c44c3a0abd33191142258485ee8e132.js %}
## 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
{% gist https://gist.github.com/shivamag00/544c372f17f804fd26180573874576ad.js %}
Create a new method in simplecoding_articles_controller.rb
{% gist https://gist.github.com/shivamag00/437784ba7bcc877d31e11a4bb1bab463.js %}
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.
{% gist https://gist.github.com/shivamag00/2e11ae978d6eee88efadf4cb9298ffcb.js %}
Let us also create a new method inside the simplecoding_articles_controller.rb
{% gist https://gist.github.com/shivamag00/58804dd123e432f1e50c9031041b4c15.js %}
The JSON response of this API looks like the following
{% gist https://gist.github.com/shivamag00/47c5b917c06f2812023f3c93cf38ee01.js %}
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
{% gist https://gist.github.com/shivamag00/b6519deed4f029a52ca543f1b2f1788a.js %}
Create a new method in simplecoding_articles_controller.rb
{% gist https://gist.github.com/shivamag00/9eb2407f6bc14df11329ac65d9d11262.js %}
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
{% github webtutsplus/simple-coding-rails %}