Backend

Modular Architecture in Go with REST and GraphQL Sharing the Same Core

Learn how to structure scalable and maintainable Go applications using a clean, modular architecture. This article includes a practical example with REST and GraphQL sharing the same core logic.

C
Carlos Noronha
Jun 22, 2025β€’7 min read
Modular Architecture in Go with REST and GraphQL Sharing the Same Core

When building Go applications, a common challenge is finding a structure that balances simplicity, flexibility, and maintainability. Although Go doesn’t enforce a specific architectural style, successful projects often adopt some common practices like separating the code into internal, cmd, and pkg directories.

This article presents a modular architecture proposal that facilitates project evolution and allows you to add or switch interfaces (REST, GraphQL, CLI, gRPC) without rewriting your business logic. To demonstrate the concept, we’ll implement a simple blog Article CRUD available via both REST (Fiber) and GraphQL (gqlgen).

🧩 Why Modularization Matters

  • Reuse business logic across different interfaces
  • Facilitate testing by isolating rules
  • Reduce coupling with frameworks and libraries
  • Allow safe evolution, such as switching Fiber to Gin or REST to gRPC

πŸ“‚ Proposed Structure

blog-api/
β”œβ”€β”€ cmd/                # Entrypoints (REST and GraphQL)
β”‚   β”œβ”€β”€ rest/           # REST server using Fiber
β”‚   └── graphql/        # GraphQL server using gqlgen
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ domain/         # Entities and interfaces
β”‚   β”œβ”€β”€ service/        # Business logic
β”‚   └── database/       # Repository implementations
β”œβ”€β”€ graph/              # GraphQL schema and resolvers
β”œβ”€β”€ pkg/                # Shared utilities (e.g., logger)

πŸ› οΈ Practical Example: Blog - Article CRUD

Here's the structure of the entity:

type Article struct {
  ID        string
  Title     string
  Content   string
  Author    string
  CreatedAt time.Time
}

We implemented methods such as CreateArticle, ListArticles, GetArticleByID, UpdateArticle, and DeleteArticle, which are exposed through REST and GraphQL interfaces β€” sharing the same business logic.

-> REST with Fiber

app.Post("/articles", func(c *fiber.Ctx) error {
  var input service.CreateArticleInput
  if err := c.BodyParser(&input); err != nil {
    return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
  }
  article, err := svc.CreateArticle(context.Background(), input)
  return c.Status(201).JSON(article)
})

-> GraphQL with gqlgen

Example of the schema:

type Query {
  articles: [Article!]!
  article(id: ID!): Article
}

type Mutation {
  createArticle(input: CreateArticleInput!): Article!
  updateArticle(id: ID!, input: UpdateArticleInput!): Boolean!
  deleteArticle(id: ID!): Boolean!
}

Resolver example:

func (r *mutationResolver) CreateArticle(ctx context.Context, input CreateArticleInput) (*Article, error) {
  return r.ArticleService.CreateArticle(ctx, input)
}

βœ… Outcomes

  • Test logic without running the server
  • Reuse code safely
  • Swap frameworks without rewriting business logic
  • Keep a clear separation between domain, infrastructure, and interfaces

... disclaimer |

This is a simple and educational project focused on structure and modularization. It is not production-ready, but can be extended with:

  • Docker and Makefile for local setup
  • Environment variables with .env files
  • Unit tests and real database integration
  • Structured logging, input validation, and authentication

πŸ“Ž GitHub ->

Full code available here: github.com/betonr/golang-base-structure


✍️ Final Thoughts

While there’s no single architecture that fits all cases, starting with a clean, modular foundation helps ensure long-term maintainability and adaptability. Whether for REST, GraphQL, or future extensions like gRPC, this kind of separation enables sustainable growth.

Questions, feedback, or contributions? πŸ“« Reach out or open an issue on GitHub!

Golang
Fiber
REST
GraphQL
Performance
Architecture
Backend
Compartilhar:
C

Carlos Noronha

Full Stack Software Engineer

Leia tambΓ©m

Backend

MongoDB Indexes: Types, Peculiarities, and Best Practices

CCarlos Noronhaβ€’Jun 01, 2025
Backend

Microservice Communication with gRPC in Node.js using NestJS

CCarlos Noronhaβ€’Jun 08, 2025