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.

Copy Text
mkdir google-translate

mkdir server

Now we will create a project using this command

Copy Text
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

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
   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.

Copy Text
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.

Copy Text
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.

Copy Text
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.

Copy Text
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”.

Copy Text
npm install react-bootstrap bootstrap

Build User Interface

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

Copy Text
<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.

Copy Text
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.

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

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

Copy Text
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.

Copy Text
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.
Copy Text
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.

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

Call the above function on onChange event as shown below.

Copy Text
<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.

Copy 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

Copy Text
go run main.go

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

Copy Text
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.

Need help to turn your website into international sensation with Google Translation API?

Book a Free 30 Min Call to Know How

Build Your Agile Team

Hire Skilled Developer From Us

[email protected]

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.

How Can We Help You?