A Practical Guide to Using oapi-codegen in Golang API Development with the Fiber Framework

Fikih Alan
5 min readNov 25, 2023

--

In the dynamic landscape of Golang web development, leveraging efficient tools and frameworks is paramount for building robust APIs. This tutorial aims to provide a hands-on guide to incorporating the oapi-codegen tool into your Golang projects, specifically within the context of the Fiber framework. By delving into the practical aspects of this integration, we’ll explore how oapi-codegen streamlines the API development process and enhances code maintainability. Whether you’re a seasoned Golang developer or just getting started, this step-by-step tutorial will equip you with the knowledge to harness the power of oapi-codegen and Fiber, facilitating the creation of scalable and well-documented APIs.

First, create a folder to set up your Golang API. I’ve named the folder “oapi-codegen-fiber.”

Navigate into the ‘oapi-codegen-fiber’ folder and execute the following command in your terminal: go mod init oapi-codegen-fiber. This command initializes a Go module for your project, establishing a solid foundation for efficient dependency management.

Now, let’s design a well-organized folder structure within the ‘oapi-codegen-fiber’ project directory to enhance the efficiency of your development process.

- api
- # Result generated api spec
- bootstrap
- handlers
- # Handlers initialization and setup
- cmd
- # Command-line application entry points
- controller
- # Controller logic and handling

Next, create an API specification as an example. Here, I’ve created an API spec named “oapi_codegen.yml,” with the following details.

openapi: "3.0.0"
info:
version: 1.0.0
x-go-package: "github.com/oapi-codegen/runtime"
title: Oapi Codegen Golang Fiber
license:
name: MIT
x-oapi-codegen-middlewares:
- Middleware

servers:
- url: http://localhost
paths:
/api/v1.0/check:
get:
summary: Check
operationId: check
responses:
'200':
description: Health check
content:
application/json:
schema:
$ref: '#/components/schemas/GlobalResponses'
components:
schemas:
GlobalResponses:
type: object
x-go-type-skip-optional-pointer: true
required:
- responseCode
- responseMessage
properties:
responseCode:
type: string
x-go-type-skip-optional-pointer: true
responseMessage:
type: string
x-go-type-skip-optional-pointer: true

Once you’ve crafted your API spec file, take the next step by downloading the oapi-codegen package outside your Go project. Installing oapi-codegen globally facilitates its usage across different projects. Refer to the official oapi-codegen documentation here for comprehensive installation instructions and additional details.

To generate the necessary files based on your API specification, execute the following command in your terminal:

oapi-codegen -package=api -generate "types,spec,fiber" oapi_codegen.yml > api/api.gen.go

This command utilizes oapi-codegen to create the api.gen.go file, aligning it with the structure defined in your API specification. The flags -package=api specify the target package, and "types,spec,fiber" indicate the components to generate.

Once this process is complete, run the following command to ensure that all the required dependencies mentioned in the generated file are downloaded:

go mod tidy

This command, go mod tidy, is essential for maintaining and organizing your project dependencies, ensuring that the necessary packages specified in api.gen.go are correctly installed.

Begin by crafting the bootstrap/bootstrap.go file, a pivotal component tailored for initializing your application. This file serves as the nexus where you set up essential configurations and initiate critical components. To adapt it to your application's unique requirements, consider configuring database connections, middleware setups, or any other fundamental aspects crucial for your project's functionality. This central initialization file plays a crucial role in establishing the groundwork for your application, ensuring it is primed and ready for execution.

package bootstrap

import "github.com/gofiber/fiber/v2/log"

type Application struct {
Logger *log.Logger
}

func NewInitializeBootsrap() Application {
app := Application{}
return app
}

Next, create the file controller/check.controller.go with the following content. This file, named check.controller.go, is responsible for handling checks within your application.

package controller

import (
"oapi-codegen-fiber/api"

"github.com/gofiber/fiber/v2"
)

// checkController handles the logic for checking the application's status.
type checkController struct {
// Add any necessary initialization for use cases or other components here.
}

// ICheckController defines the interface for the checkController.
type ICheckController interface {
Execute(c *fiber.Ctx) error
}

// NewCheckController creates a new instance of checkController.
func NewCheckController() ICheckController {
return &checkController{}
}

// Execute implements the ICheckController interface.
func (*checkController) Execute(c *fiber.Ctx) error {
var apiRes api.GlobalResponses
apiRes.ResponseCode = "200"
apiRes.ResponseMessage = "Go is running!"
return c.JSON(apiRes)
}

This file, check.controller.go, encapsulates the logic for checking the application's status. The Execute method handles the check and returns a JSON response indicating that Go is running.

Now, create the file handlers/handler.go with the following content. This file, named handler.go, serves as a bridge between your API routes and controllers.

package handlers

import (
"oapi-codegen-fiber/bootstrap"
"oapi-codegen-fiber/controller"

"github.com/gofiber/fiber/v2"
)

// MyHandler represents the handler struct.
type MyHandler struct {
Application bootstrap.Application
}

// NewServiceInitial creates a new instance of MyHandler.
func NewServiceInitial(app bootstrap.Application) MyHandler {
return MyHandler{
Application: app,
}
}

// ServerInterfaceWrapper wraps controller interfaces.
type ServerInterfaceWrapper struct {
CheckHandler controller.ICheckController
}

// Check implements api.ServerInterface.
func (h *ServerInterfaceWrapper) Check(c *fiber.Ctx) error {
return h.CheckHandler.Execute(c)
}

This file, handler.go, acts as an intermediary between your API routes and controllers. The ServerInterfaceWrapper struct wraps the controller interfaces, and the Check method invokes the corresponding controller method for the check operation.

Create a cmd/handlers/check.handler.go for initiate check.controller.go

package handlers

import "oapi-codegen-fiber/controller"

func (h *MyHandler) CheckHandler() controller.ICheckController {
checkController := controller.NewCheckController()
return checkController
}

Create the cmd/main.go file with the following comprehensive content. This main.go file serves as the central entry point for your application, orchestrating the initialization of key components and defining API routes.

package main

import (
"oapi-codegen-fiber/api"
"oapi-codegen-fiber/bootstrap"
"oapi-codegen-fiber/cmd/handlers"

"github.com/gofiber/fiber/v2"
)

func main() {
// Initialize the application's bootstrap components.
app := bootstrap.NewInitializeBootsrap()

// Create a new Fiber instance.
f := fiber.New()

// Serve the Swagger UI at the "/swagger" endpoint.
f.Static("/swagger", "cmd")

// Define the API versioned group.
f.Group("/api/v1.0")

// Initialize the application-specific handlers.
serve := handlers.NewServiceInitial(app)
checkController := serve.CheckHandler()

// Create a wrapper for the controller interfaces.
wrapper := &handlers.ServerInterfaceWrapper{
CheckHandler: checkController,
}

// Register API handlers.
api.RegisterHandlers(f, wrapper)

// Start the server on port 3000.
f.Listen(":3000")
}

This main.go file now includes comments to guide you through the different sections. It initializes the application's bootstrap components, sets up the Swagger UI, defines the API versioning, initializes handlers, and starts the server on port 3000.

To view the results of the API you’ve built, follow these steps:

  1. Open a terminal.
  2. Navigate to the root directory of your project.
  3. Run the following command:
go run cmd/main.go

Now, open Postman or any other tool of your choice to check the results of the application. Access the following endpoint: “http://localhost:<port>/api/v1.0/check”

Thank you for reading this tutorial! If you have any further questions or want to explore the full code, you can find it on our GitHub repository here.

Feel free to explore the complete implementation, raise issues, or contribute to make it even better. Happy coding!

--

--

Fikih Alan

Experienced backend developer (3+ years) in PHP, Laravel, SQL, NoSQL, Nest Js, GO, and Express Js. Specializes in maintaining clean and efficient code.