Table of Contents

Introduction

Have you ever wondered how to develop a translator of your own? Did you ever encounter a requirement where you need to develop a feature to translate texts? Are you struggling to develop a translator? Then this tutorial on how to translate texts with Google Translate API using Golang is for you! Let’s see what are we covering in today’s tutorial.

Tutorial Goal: Translate Texts with Google Translate API

  • Understanding and Implementation of RapidAPI Hub
  • Server Side Logic to translate texts
  • Create APIs
  • Building User Interface
  • Source Code: Demo application to translate texts with Google Translate API

Initial Set Up

Let’s get started with the backend first. Create a folder called “google-translate”. In this folder create a new folder called “be”. In this folder, we will do our backend code.

mkdir google-translate

mkdir server

Now we will create a project using this command

go mod init translate
Initial Setup

RapidAPI Hub Set Up

Now on this website RapidAPI Hub and create an account. If you have already, then just log in.

In the Search API text box, search for Google Translate. You will be redirected to Google Translate API Documentation.

Further, click on the Subscribe to Test button. You will be displayed a pricing chart as shown below.

RapidAPI Hub Set Up

Now, subscribe to the Basic plan of $0.00/month. Don’t choose plan which costs money.

Subscription successful

You have now successfully subscribed. You will be provided “X-RapidAPI-Key” for sending requests. Please keep that key secret.

Basic Project Set Up

Now, moving on to the coding part. Our demo app will consist of two main folders for the backend and front end, respectively, server and client.

The folder structure would something like this:

Basic Project Set Up

In the helpers.go file we will create a struct called ReqBody.

// helpers.go

type ReqBody struct {
   SourceLang string `json:"sourceLang"`
   TargetLang string `json:"targetLang"`
   SourceText string `json:"sourceText"`
}

Define the Google Translate URL as the constant value. We will send the requests to this URL.

const translateURL = "https://google-translate1.p.rapidapi.com/language/translate/v2"

Are you looking for Golang experts who take care of understanding your project’s requirements to meet them accurately?
Bacancy at the rescue! We understand your project’s importance. Trust us! Contact Bacancy now and hire Golang developer with high problem-solving skills and architectural knowledge.

Server Side Logic

Open helpers.go file and use the below code.

func ReqTranslate(body *ReqBody) ([]byte, error) {
   var str2 string
   str2 = ""
   str2 = str2 + "q=" + body.SourceText
   str2 = str2 + "&target=" + body.TargetLang
   str2 = str2 + "&source=" + body.SourceLang

   payload := strings.NewReader(str2)

   req, err := http.NewRequest("POST", translateURL, payload)
   if err != nil {
       return []byte(""), err
   }

   req.Header.Add("content-type", "application/x-www-form-urlencoded")
   req.Header.Add("Accept-Encoding", "application/gzip")
   req.Header.Add("X-RapidAPI-Key", "")
   req.Header.Add("X-RapidAPI-Host", "google-translate1.p.rapidapi.com")

   res, err := http.DefaultClient.Do(req)
   if err != nil {
       return []byte(""), err
   }

   defer res.Body.Close()
   body1, err := ioutil.ReadAll(res.Body)
   if err != nil {
       return []byte(""), err
   }

   defer res.Body.Close()

   if res.StatusCode == http.StatusTooManyRequests {
       return []byte(""), errors.New("Too many requests")
   }
   return body1, nil
}

Explanation

To Translate Texts and Generate Payload

The API which we have used here requires the source language, text and target language. So we have structured the below code as per the requirements. Create the payload containing source language, text, and target language.

var str2 string
   str2 = ""
   str2 = str2 + "q=" + body.SourceText
   str2 = str2 + "&target=" + body.TargetLang
   str2 = str2 + "&source=" + body.SourceLang

   payload := strings.NewReader(str2)

Create a New POST Request

Create a new “post” request and add headers. You have to replace < YOUR_KEY > with X-RapidAPI-Key.

req, err := http.NewRequest("POST", translateURL, payload)
   if err != nil {
       return []byte(""), err
   }

   req.Header.Add("content-type", "application/x-www-form-urlencoded")
   req.Header.Add("Accept-Encoding", "application/gzip")
   req.Header.Add("X-RapidAPI-Key", "")
   req.Header.Add("X-RapidAPI-Host", "google-translate1.p.rapidapi.com")

   res, err := http.DefaultClient.Do(req)
   if err != nil {
       return []byte(""), err
   }

To Deliver the Response or Error Message

The below code will either deliver a response or an error message.

defer res.Body.Close()
   body1, err := ioutil.ReadAll(res.Body)
   if err != nil {
       return []byte(""), err
   }

   defer res.Body.Close()

   if res.StatusCode == http.StatusTooManyRequests {
       return []byte(""), errors.New("Too many requests")
   }
   return body1, nil

Fetch all the Languages

Create another function to get all the languages that Google Translate provides in the helpers.go file.

func GetLanguages() ([]string, error) {
   var language []string
   url := "https://google-translate1.p.rapidapi.com/language/translate/v2/languages"
   req, err := http.NewRequest("GET", url, nil)
   if err != nil {
       return language, err
   }
   req.Header.Add("Accept-Encoding", "application/gzip")
   req.Header.Add("X-RapidAPI-Key", "1f567f5ad9msh566e3bdad55c972p12adadjsnbca1e41ae0e7")
   req.Header.Add("X-RapidAPI-Host", "google-translate1.p.rapidapi.com")

   res, err := http.DefaultClient.Do(req)
   if err != nil {
       fmt.Println("error in request", err)
   }

   defer res.Body.Close()
   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
       return language, err
   }
   var rs Resp
   err = json.Unmarshal(body, &rs)
   if err != nil {
       return language, err
   }
   for _, v := range rs.Data.Languages {
       language = append(language, v.Language)
   }
   return language, nil
}

Create a Struct to Unmarshal Data

We need to create a Struct to unmarshal data coming from the third party API.

type Resp struct {
   Data struct {
       Languages []struct {
           Language string `json:"language"`
       } `json:"languages"`
   } `json:"data"`
}

The function will return a slice of string and error that contains all the languages Google translate provides. Change YOUR_KEY with your X-RapidAPI-Key.

var rs Resp
   err = json.Unmarshal(body, &rs)
   if err != nil {
       return language, err
   }
   for _, v := range rs.Data.Languages {
       language = append(language, v.Language)
   }
return language, nil

Create APIs

Now in the api.go file which is in the controller/api directory.

We will create 2 APIs
1. To fetch all languages from Google Translate
2. To translate the text from the source language to the target language.

To Fetch All Languages from Google Translate

The below API will fetch all the languages from google translate.

func GetAllLanguagesFromGoogleTranslate(w http.ResponseWriter, r *http.Request) {
   w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
   w.Header().Set("Access-Control-Allow-Methods", "POST, GET")
   w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")

   language, err := helpers.GetLanguages()
   if err != nil {
       w.WriteHeader(http.StatusInternalServerError)
       w.Write([]byte("Internal server error"))
       return
   }
   langBytes, err := json.Marshal(language)
   if err != nil {
       w.WriteHeader(http.StatusInternalServerError)
       w.Write([]byte("Internal server error"))
       return
   }

   w.Write(langBytes)
}

Explanation

Prevent the CORS Error

Use the below code to prevent the cors error from the front end.

   w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
   w.Header().Set("Access-Control-Allow-Methods", "POST, GET")
   w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")

The below code will return the slice of string that contains all the languages and errors if any.

res, err := http.DefaultClient.Do(req)
   if err != nil {
       fmt.Println("error in request", err)
   }

To translate the text from the source language to the target language.

The below API is used to send the translated data to the client side. For that, the below helper function “ReqTranslate” will return us translated text and errors if any.

func TranslateTheText(w http.ResponseWriter, r *http.Request) {
   w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
   w.Header().Set("Access-Control-Allow-Methods", "POST, GET")
   w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
   reqbody, err := ioutil.ReadAll(r.Body)
   if err != nil {
       fmt.Printf("error on reading body: %v", err)
       w.WriteHeader(http.StatusBadRequest)
       w.Write([]byte("Bad request"))
       return
   }

   var rqBody helpers.ReqBody

   err = json.Unmarshal(reqbody, &rqBody)
   if err != nil {
       fmt.Printf("error in unmarshaling body: %v", err)
       w.WriteHeader(http.StatusInternalServerError)
       w.Write([]byte("Internal server error"))
       return
   }

   translatedText, err := helpers.ReqTranslate(&rqBody)
   if err != nil {
       fmt.Println("Error in translating", err)
       w.WriteHeader(http.StatusInternalServerError)
       w.Write([]byte("Internal server error"))
       return
   }
   w.Write(translatedText)
}

Now, create the server in the main.go file as shown below.

package main

import (
   "net/http"

   "translate/controller/api"
)

func main() {

   http.HandleFunc("/getalllanguages", api.GetAllLanguagesFromGoogleTranslate)
   http.HandleFunc("/translate", api.TranslateTheText)

   http.ListenAndServe(":8080", nil)

}

Client Side Set Up and User Interface

Run the below command in the “google-translate” directory to create “client” folder.

npx create-react-app client

Install Dependency

We need to use bootstrap to style our component. By the below command, we can add bootstrap as npm dependency and use the classes of “react-bootstrap”.

npm install react-bootstrap bootstrap

Build User Interface

The App.js file will look like this to build the user interface.

<div className="m-100">
     <div className="d-flex gap-3 m-4 justify-content-around">
       <select
         className="form-select w-50"
         aria-label="Default select example"
         name="from"
         value={form.from}
         onChange={({ target }) => handleChange(target)}
       >
         {languages.map(lang => <option key={lang} value={lang}>{lang}</option>)}
       </select>
       <select
         className="form-select w-50"
         aria-label="Default select example"
         name="to"
         value={form.to}
         onChange={({ target }) => handleChange(target)}
       >
         {languages.map(lang => <option key={lang} value={lang}>{lang}</option>)}
       </select>
     </div>
     <div className="d-flex gap-3 m-4 ">
       <label>Enter text to translate: </label>
       <div className="form-floating">
         <textarea
           className="form-control"
           id="inputText"
           name="text"
           value={form.text}
           onChange={({ target }) => handleChange(target)}
         ></textarea>
       </div>
       <div className="form-floating">
         <textarea
           className="form-control ml-200"
           id="traslatedText"
           name="traslatedText"
           value={form.traslatedText}
           onChange={({ target }) => handleChange(target)}
         ></textarea>
       </div>
     </div>
     <div>
       <button
         type="button"
         className="btn btn-primary mx-4"
         onClick={handleTranslate}
       >
         Translate
       </button>
     </div>
   </div>

Integrate APIs and Store Data

Use the “getAllLanguages()” function to fetch the languages.

async function getAllLanguages() {
 const response = await fetch(`http://localhost:8080/getalllanguages`, {
   method: 'GET',
   headers: {'Content-Type': 'application/json'},
 })
 return await response.json();
}

Declare local state and set method using useState.

const [languages, setLanguages] = useState([]);

Call the above API through “getAllLanguages()” with the help of useEffect() hook as shown below.

useEffect(() => {
   const data = getAllLanguages()
   data.then(res => {
     setLanguages(res)
   })
 }, []);

Create an object named “form” to use it as a payload and a function handleTranslate() to call translate API.

const [form, setForm] = useState({
   to: "",
   from: "",
   text: "",
   traslatedText: ""
 });

Translate API requires source language, target language and source text.

  • Source language is the language from which you want to translate. The text user wants to translate.
  • Target language is the language in which you want your translated output.
async function handleTranslate() {
   const data = {
     sourceLang: form.from,
     targetLang: form.to,
     sourceText: form.text
   }
   const response = await fetch(`http://localhost:8080/translate`, {
     method: 'POST',
     body: JSON.stringify(data)
   })
   response.json().then(res => {
     handleChange({
       name: 'traslatedText',
       value: res.data.translations[0].translatedText
     })
   })
 }

Then there is another function that will help us to change the state of the form variable.

const handleChange = ({ name, value }) => {
   setForm({
     ...form,
     [name]: value
   });
 };

Call the above function on onChange event as shown below.

<div className="d-flex gap-3 m-4 justify-content-around">
       <select
         className="form-select w-50"
         aria-label="Default select example"
         name="from"
         value={form.from}
         onChange={({ target }) => handleChange(target)}
       >
         {languages.map(lang => <option key={lang} value={lang}>{lang}</option>)}
       </select>
       <select
         className="form-select w-50"
         aria-label="Default select example"
         name="to"
         value={form.to}
         onChange={({ target }) => handleChange(target)}
       >
         {languages.map(lang => <option key={lang} value={lang}>{lang}</option>)}
       </select>
     </div>

Use method handleTranslate() to translate the source text.

<button
   type="button"
   className="btn btn-primary mx-4"
   onClick={handleTranslate}
>
   Translate
</button>

Run the Application

Now, in the server folder start the backend folder by running the below command. It will start the server on port number

go run main.go

This will start the server on port number 8080. And for the front end, we need to run the command.

npm start

To start the front-end server and our application will be on URL http://localhost:3000. Our front-end interface will look like this.

front-end interface

Github Repository: google-translate-api-example

Visit the github repository to clone the source code and play around with the code.

Conclusion

So this was about how to translate texts with Google Translate API using Golang. We hope the step-by-step guideline was helpful to you. If you are a Golang enthusiast then visit Golang tutorials to grab fundamental and advanced knowledge. Contact us if you have any queries, topics, or suggestions.

Ashvin Kumbhani

Ashvin Kumbhani

Director of Engineering at Bacancy

Versatile tech leader driving innovation, scalability, and mentorship in engineering.

MORE POSTS BY THE AUTHOR
SUBSCRIBE NEWSLETTER

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.