Building the ImageGeneratorService in Go for Image Generation Services

Introduction to the Image Generator Service

Welcome to the third lesson of our course on building an image generation service with Go! In our previous lessons, we created the PromptManager to format user inputs into detailed prompts and the ImageManager to handle storing and processing generated images. Now, we're ready to build the core component that brings everything together: the ImageGeneratorService.

The ImageGeneratorService is the central piece of our application that will:

  1. Connect to Google's Gemini API to generate images
  2. Use our PromptManager to format user inputs into effective prompts
  3. Store generated images using our ImageManager
  4. Provide access to all previously generated images

This service acts as the bridge between our application's components and the external AI service that actually creates the images. By encapsulating all the image generation logic in a dedicated service struct, we maintain a clean separation of concerns in our application architecture.

In this lesson, we'll implement this service step by step, from setting up the API client to handling responses and errors. By the end, you'll have a fully functional image generation service that you can later integrate into a Go web application using Fiber.

Re-visiting the Gemini API

For most Generative AI cases with Gemini, you can use the generative-ai-go/genai Go module for interacting with Gemini. As of this writing, however, this module does not support generative images.

Because of this, we are going to use the REST API directly with Go to request the images, which we will later encapsulate.

We've included a helper function to access the Gemini Image Generation API via REST in util.GenerateGeminiImages(prompt string, options *ImageGenerationParameters) ([][]byte, error). This was covered in a previous course so we won't go over it here. You can find this helper in the util folder of your practices.

Creating the ImageGeneratorService

type ImageGeneratorService struct {
    imageManager *models.ImageManager
    promptManager *models.PromptManager
}

func NewImageGeneratorService() *ImageGeneratorService {
    return &ImageGeneratorService{
        imageManager: models.NewImageManager(),
        promptManager: &models.PromptManager{},
    }
}

In this constructor, we're doing two important things:

  1. Creating an instance of our ImageManager struct to handle storing and retrieving images.
  2. Creating an instance of our PromptManager struct to handle retrieval of our prompts.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal