Development Process — Summer Internship 2020

Hugo Gomes
Nest Collective Writing Wall
6 min readSep 16, 2020

Hello there, fellow humans! 🧍🧍‍♀️

As we are coming to the end of this wonderful internship at Nest Collective, we want to talk a little bit about how we developed our project throughout the summer.

Our Project 🌟

Looking back at the problems we diagnosed in the Design Sprint we decided to create a web application with some information about the city downtown.

A quick overview of how our system relates to our users and 3rd party integrations

For this, the tech stack we used was Angular for the frontend and Ruby on Rails (RoR) for the backend (this was predefined). As none of the developers had experience with Angular and RoR, we had to learn more about it as we progressed. For the database, we chose PostgreSQL, as both of us had experience with it.

Our project has two components, as previously said: an API server (Backend) and a Web Client (Frontend). It follows a client-server model where the communication is done through request-response messaging.

The API follows the MVC (Model View Controller) pattern since Rails enforces it. As we are programming an API server, we have models, controllers but we don’t have views, we have serializers that format the data we then send to the Web Client.

Our Frontend is an SPA (Single Page Application). This means that our app dynamically rewrites the web page content instead of the default browser method of loading the entire new page.

The Web Client also follows a similar MVC pattern, where we have interfaces for specifying the models coming from the API, the services play the role of controllers, keeping the data every component uses and then the components as views, having small complexity and mostly showing the models.

The developers

The Backend 🗄️

To store a lot of data about the city downtown, we had to separate it and process it in a way we could allow quick searches. We created many entities, in a star-like schema, with the most important entity in the center. This entity had several relationships with other entities. This was also why we chose PostgreSQL, we thought it was the best technology to store our data, as we have many relations between our models.

Our API follows a RESTful convention and sends the data in the JSON format, to improve performance and data correctness, we used the gem JSON:API Serializer.

As we wanted to allow users to register, we used Google’s and Facebook’s login mechanism. For this, we had to use some Ruby gems like Devise, OmniAuth, and Devise Token Auth, as well as OmniAuth Google OAuth2 Strategy and OmniAuth Facebook.

This task took a little time and patience, as this combination is not well polished and few people had used it. But after some banging head against the wall, we succeeded! 👍

With Devise, we were able to have a authentication system which gives the users access to more features. Devise Token Auth provides a token-based authentication. This authentication method allowed us to easily authenticate the users, validate their authentication and manage their permissions. The tokens are provided by Omniauth which also gives us permission to access some users’ data like their name, email and profile picture. Devise Token Auth depends on Devise since it only adds a way to authenticate with tokens.

To allow uploading images, we used the gem Carrierwave, in cooperation with Amazon S3 Bucket, as with this service, Amazon provides an easy way to store data. Carrierwave enables file uploading and Amazon S3 Bucket file hosting.

We had the need for an admin dashboard that would help us manage our data. We got suggested Rails Admin and since it ticked all our needs, we decided to use it. This prevented us from spending more time developing a solution from scratch.

For testing, we used the FactoryBot Rails and Faker gems. FactoryBot allows the creation of various instances of a class with straightforward syntax. Faker provides an enormous collection of random text and images to improve our test data.

We tested our controllers’ functionality since our models are really simple and don’t have much complexity associated with and the controllers are what manage our business logic. We made our tests to make sure that our code works in all situations, thus testing its completeness.

Finally, to ensure that our code was maintainable, readable, and secure, we used RuboCop and Brakeman gems. RuboCop is a static code analyzer and code formatter that ensures that the community coding guidelines are followed. Brakeman is a static security analysis tool that checks for security vulnerabilities.

The Frontend 🌐

Since we had to use Angular for the Frontend, we had to learn more about TypeScript, as we had little to none experience.

For the routing, we used the Angular Router module since we used it in our training and because it is the standard.

We had the need to create custom services to support our components. They were useful to store some data that needed to be shared in multiple components, therefore making its manipulation easier. Besides these services, we created a special one for abstracting our API requests.

To support our data and taking advantage of Typescript’s strict and structural typing, we declared custom interfaces for our API Model data types so it would be easier to detect eventual bugs.

In our forms, we used the Angular Forms module. We decided to use the Reactive forms approach with the FormBuilder class since it provided an easy way to structure, modify and validate form’s data.

To ensure a correct transfer of data, we used an NPM module from RedLight Software, Denormalize JSON API. This module transforms the JSON API data into a simpler form, easier to work with.

For user authentication, we used an NPM module called Angular Token, as it is compatible with the Backend gem Devise Token Auth. This allowed us to get simple information from users, like their emails, names, and profile pictures, while keeping all the data secure.

To graphically depict Coimbra’s downtown we needed a map API, so we decided to use MapBox GL, since one of us developers had experience with it and it allowed us to progress quickly in this matter.

After some code reviews, we were introduced to Angular Barrels — a barrel is a way to roll-up exports from several modules into a single module — and started to use them, improving our imports and organization. We also organized our code to be easier to maintain, separating components and services into proper folders. We also separated these components into atoms and blocks. Atom components are simpler components that we reused in many pages. Block components are pages or more complex components.

To ensure the quality of our code, we made End-to-End tests with Cypress and used TSLint to analyze our code.

Pipelines ⚙️

Since we were running many tests to our code, whether it was on the backend or the frontend, we had them run automatically so that it would remind us to correct any problem we didn’t know we had. To do this, we had to configure our GitLab repository to run two pipelines, one to run the functionality tests and the linter to the Backend and another to run End-to-End tests and the code analysis to the Frontend.

After these pipelines, we also created one to deploy our code into production, as we are using Heroku. This allows us to, without concerns, have our project running on our hosting platform.

This internship, despite being the Covid-19 Limited Edition™️ 😷, was our opportunity to explore new technologies, learn how to work in a team and in an agile development process. We took this opportunity and tried our best to make a successful project and we think we might just have done it! 🙌

Thanks to Dinis Marques and Filipe Abreu for all the reviews and suggestions, it made our jobs much easier! 🙏

Watch out for our next post, the designers still have a word to say!

--

--