Building a Movie Recommendation API in Go (Part 1): From Graph to API Architecture
In the previous articles, we learned how graph databases model connected data and how Neo4j enables recommendation engines through graph…
Building a Movie Recommendation API in Go (Part 1): From Graph to API Architecture

In the previous articles, we learned how graph databases model connected data and how Neo4j enables recommendation engines through graph traversals.
At this point, we have a graph capable of answering questions like:
- Which movies share the same genre?
- Which users have similar preferences?
- Which movies should be recommended next?
However, a graph database alone is not enough.
Applications don’t communicate directly with Neo4j. Instead, they interact with an API responsible for validating requests, executing business rules, querying the database, and returning meaningful responses.
This article begins the implementation side of the series.
We’ll explore how the Movie Suggestion project is organized, why its architecture was designed this way, and how a good project structure makes the application easier to maintain and evolve.
By the end of this article, you’ll understand:
- Why application architecture matters
- How the project is organized
- The responsibility of each package
- How requests flow through the application
- Why this architecture makes it easy to add new recommendation algorithms
Why Architecture Matters
When building a small application, it’s common to place everything in a single package.
As the application grows, this approach quickly becomes difficult to maintain.
Imagine adding a new recommendation algorithm.
Where should the implementation go?
Should it be added to the HTTP handler?
Should it query Neo4j directly?
Should it contain business rules?
Without clear boundaries, responsibilities become mixed together.
The result is code that is harder to understand, harder to test, and harder to extend.
Good architecture solves this problem by giving every part of the application a single responsibility.
Thinking About Layers
A useful way to think about an application is to imagine a restaurant.
Customers don’t walk into the kitchen and prepare their own meals.
Instead:
- A customer places an order.
- A waiter receives the request.
- The kitchen prepares the meal.
- Ingredients come from storage.
- The finished meal is returned to the customer.
An API follows a similar flow.
Client
|
HTTP Request
|
HTTP Handler
|
Business Logic
|
Repository
|
Neo4j
Each layer has one responsibility.
This separation keeps the application simple and maintainable.
The Architecture Used in the Movie Suggestion Project
The Movie Suggestion project follows the principles of Clean Architecture.
The goal is simple:
Business rules should not depend on external technologies.
That means the recommendation algorithms should not know:
- Which database is being used.
- Which HTTP framework is being used.
- How requests arrive.
- How responses are returned.
Instead, they only focus on solving the recommendation problem.
Everything else becomes infrastructure.
This makes the application much easier to evolve over time.
Organizing the Project
Instead of placing every file inside the same directory, the project is divided into packages with clear responsibilities.
A simplified structure looks like this:
cmd/
internal/
api/
recommendation/
repository/
graph/
model/
config/
Each directory has a specific purpose.
cmd/
The cmd directory contains the application's entry point.
Think of it as the front door of the application.
Its responsibility is to:
- Load configuration
- Create dependencies
- Start the HTTP server
Nothing more.
Business rules should never live here.
internal/api
This package receives HTTP requests.
For example:
GET /recommendations/{userId}
The API layer is responsible for:
- Reading request parameters
- Validating input
- Calling the appropriate service
- Returning JSON responses
Notice what it does not do:
- It does not build Cypher queries.
- It does not calculate recommendation scores.
- It does not access Neo4j directly.
Those responsibilities belong elsewhere.
internal/recommendation
This is the heart of the application.
Every recommendation algorithm lives here.
For example:
- Content-Based Recommendation
- Collaborative Filtering
- Hybrid Recommendation
Each algorithm receives information, processes it, and returns recommended movies.
Because this layer is isolated, adding a new recommendation strategy becomes straightforward.
internal/repository
Repositories are responsible for communicating with Neo4j.
Think of them as translators.
The recommendation layer says:
“Give me the movies watched by this user.”
The repository translates that request into a Cypher query.
For example:
Recommendation Service
|
Repository Interface
|
Neo4j Repository
|
Cypher Query
|
Neo4j
This keeps database-specific code out of the business logic.
internal/graph
This package contains everything related to the Neo4j connection.
Typical responsibilities include:
- Opening database sessions
- Managing transactions
- Configuring the Neo4j driver
- Handling connection details
If the application ever needs a different database, most of the changes remain isolated here and in the repository implementations.
internal/model
Models represent the application’s domain.
Examples include:
User
Movie
Genre
Actor
Director
Recommendation
These models describe the business concepts rather than database tables.
This distinction helps keep the code expressive and easier to understand.
internal/config
Configuration should have a single home.
This package is responsible for loading values such as:
- Neo4j URI
- Username
- Password
- HTTP port
- Environment variables
Keeping configuration separate avoids scattering these values throughout the codebase.
How a Request Flows Through the Application
Now that we’ve seen the project structure, let’s follow a recommendation request from start to finish.
Suppose a client calls:
GET /recommendations/user-123
The request flows through the application like this:
Client
|
HTTP Handler
|
Recommendation Service
|
Repository
|
Neo4j
|
Repository
|
Recommendation Service
|
HTTP Handler
|
JSON Response
Each layer performs exactly one task before passing control to the next.
This simple flow makes the application predictable and easy to debug.
Why This Structure Makes the Project Easier to Extend
Imagine we want to introduce a brand-new recommendation algorithm based on user ratings.
Would we need to rewrite the HTTP layer? No.
Would we need to change Neo4j’s connection code? No.
Would we need to modify the existing recommendation algorithms? Again, no.
Instead, we simply add a new implementation to the recommendation package and register it with the strategy responsible for selecting algorithms.
Because responsibilities are isolated, new features can be introduced with minimal impact on the rest of the application.
This is one of the biggest advantages of a well-designed architecture.
Conclusion
Before writing complex business logic, it’s important to build a solid foundation.
A clear architecture helps developers understand the project, simplifies testing, reduces coupling, and makes future changes much easier.
In this article, we explored:
- Why application architecture matters
- The principles behind the Movie Suggestion project
- The responsibility of each package
- How requests flow through the application
- Why a layered architecture simplifies maintenance and future growth
In the next article, we’ll move one level deeper and explore how the repository layer communicates with Neo4j, how Cypher queries are encapsulated, and how the recommendation service remains independent from the database implementation.
Source Code
The complete project is available on GitHub:
메타데이터
- post_id
- bebc5e09afac
- slug
- building-a-movie-recommendation-api-in-go-part-1-from-graph-to-api-architecture-bebc5e09afac
- url
- https://medium.com/@william.cesar.santos1/building-a-movie-recommendation-api-in-go-part-1-from-graph-to-api-architecture-bebc5e09afac
- canonical_url
- https://medium.com/@william.cesar.santos1/building-a-movie-recommendation-api-in-go-part-1-from-graph-to-api-architecture-bebc5e09afac
- author_url
- https://medium.com/@william.cesar.santos1
- status
- ok
- fetched_at
- 2026-06-26 21:52:29