Developing a Microservice to Check Content Availability on a Platform (Spotify, Deezer, Netflix)
Tags: python, flask, webdev, javascript
Published: 2024-03-01 00:04:46

# Introduction and Recap

Hello Everyone, previously I wrote an article on tabnews.com.br talking about [RecomendeMe](www.recomendeme.com.br): RecomendeMe is a developed platform that allows users to submit cultural recommendations to a community. These recommendations can include movies, music, books, TV series, local events, and more. The goal is to create a platform where users can share their favorite cultural discoveries with others without the need for recommendations by artificial intelligence algorithms.

**One of the application's features was the ability to know on which of the main platforms a certain content would be available as soon as the user submitted the recommendation. For this, I developed a Flask microservice that receives a POST request and, based on the artist's name and album, saves the link in a database.**

## Architecture and Performance Issue

Since I had already developed a JavaScript API to save the recommendation in JSON format, with the following properties:


```json
{
  "title": "Breaking - Phobia",
  "user": "username",
  "description": "Recommendation description.",
  "img": "https://image-url.com/image.jpg",
  "created_at": "2024-02-12T12:00:00Z",
  "updated_at": "2024-02-12T12:00:00Z",
  "reclink": "https://recommendation-link.com"
}

```

I thought the API was already assuming too many responsibilities by including the task of directly fetching these links in the controller or in an internal service of the API itself. This could overload the API with too many duties. Therefore, the idea of ​​creating a Flask microservice dedicated to this function arose. When adding the microservice to the application's architecture, I encountered two possibilities for communication between the API and the microservice (although the draft may seem confusing, in my mind it makes sense hahaha)

<img src="https://i.ibb.co/gd2bzmQ/Whats-App-Image-2024-02-15-at-14-55-08.jpg" alt="Whats-App-Image-2024-02-15-at-14-55-08" border="0"></a>

**(1) The first possibility involved communication between the microservice and the API through the POST method, following this logic**

The user submits a content recommendation:

(POST -> API -> Microservice and Database)

The API redirects a POST method to the Microservice, which receives the request, fetches the links, and then sends a PUT back to the API to update the links:

(Microservice -> Search Engines -> PUT -> API -> Database)

Although this approach offered more direct communication between the API and the Microservice, from a performance point of view, there was a risk of overloading the API. Additionally, due to network requests, communication failures could occur.

**(2) The second possibility consisted of a simpler, but less communicative approach to the API, meaning the API would not be notified by the PUT method about updates to the database made by the Microservice.**

In simpler terms, whenever a recommendation was made, a POST method would be sent from the API to the Microservice, and the Microservice would update the database with an UPDATE method, using only the title and user parameters

**API -> POST -> Microservice -> Search Engines -> Database.**

One advantage of developing this microservice in Python was the ability to include several automations. For example, instead of requiring the user to provide the image URL, now this is no longer necessary, as the Flask module includes a Bing module that searches for the image and returns a corresponding URL to the image available on the internet.

```python

@app.route('/update_image', methods=['POST'])
def update_image():
        try:
            # Get POST data
            data = request.json
            name = data.get('name')
            recommendation_id = data.get('id')

            # Search for an image based on the artist's name and album
            image_urls = bing_image_urls(name, limit=1)

            # Check if image URLs were found
            if image_urls:
                image_url = image_urls[0]

                # Connect to the MySQL database
                connection = mysql.connector.connect(**db_config)
                cursor = connection.cursor()

                # Update the record in the database with the found image link
                update_query = "UPDATE recommendations SET img = %s WHERE id = %s"
                cursor.execute(update_query, (image_url, recommendation_id))
                connection.commit()
```


## Change in Database Structure

Since the goal was to save multiple links, I considered some possibilities regarding the RecLink parameter. I thought about making the API return an array containing the links, but this would require a complete update of the application's front-end logic to handle these new data types. Another option would be to create a specific table for the links, resulting in something like this:

```sql
CREATE TABLE rec_links (
  id INT AUTO_INCREMENT PRIMARY KEY,
  recommendation_id INT,
  platform VARCHAR(50),
  link VARCHAR(255),
  FOREIGN KEY (recommendation_id) REFERENCES recommendations(id)
);
```

```sql
ALTER TABLE recommendations
ADD COLUMN rec_link_deezer VARCHAR(255),
ADD COLUMN rec_link_spotify VARCHAR(255),
ADD COLUMN rec_link_ytmusic VARCHAR(255);
```

Although not a good practice and something that would certainly result in an expansion of columns in the database, I found it easier and more practical since I had prior knowledge of how many and which platforms would be present. Thus, I created the columns rec_link_deezer, rec_link_spotify, and rec_link_ytmusic to store the links of each platform directly in the recommendations table.

**Results**

Separation of concerns: the microservice can handle specific update logic separately from the main API.

Scalability: if the update logic becomes complex or heavy, separation into a microservice can help scale that part of the system independently.

Granular control: you have more control over the update logic and can easily adjust the microservice's behavior as needed.

Previously, in the form, it was necessary to include on which platform that content was consumed and some reference image, now, with the update, only a Username, recommendation, and a comment about are required.

<img src="https://i.ibb.co/GxJ5kR0/Whats-App-Image-2024-02-15-at-16-19-17.jpg" alt="Whats-App-Image-2024-02-15-at-16-19-17" border="0">
<br>
<img src="https://i.ibb.co/PcTK73S/Whats-App-Image-2024-02-15-at-16-17-35-1.jpg" alt="Whats-App-Image-2024-02-15-at-16-17-35-1" border="0">

## Contact

For those interested in the project or wishing to contribute in any way,

- Email: lucasmatheus.matheus231@gmail.com
- LinkedIn: Lucas Matheus