Writing answering system using Go and YottaAnaswers API


This year we launched our API for people to use. In this post, we are going to use this api to create a simple answering application in Golang.

YottaAnswers API

There are two versions of API, Public and Private. The Public version is free, and there is no need for registration to use this API. Downside of this version is that it has a rate-limit and that you will share the system with other Public users. If you want better performance, you should use the Private version, where you can register using email, where you will get your API key. It will give you 1000 requests per day, and 30000 requests overall.

Using Golang for RESTful API

One of the main reasons for using Go for RESTful API applications are performance and simplification of deployment. Compared to other popular programming languages, like NodeJS and Python, performance of Go is significantly improved, mostly because it is statically typed, compiled and based on C language.

Let’s start

First thing we will do is of course initiate our project and create main file ( I assume that you already have go installed on your computer ):

yottaanswers$ go mod init yottaapi                                                                                                                                                                                     yottaanswers$ mkdir main                                                                                             yottaanswers$ touch main/main.go 

So when we open the main file, we need to import some packages. For this project there is no need for any additional dependencies, all we need is in-built into language.

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

We use json package for encoding responses from API, fmt is package for I/O functionalities, http is for http calls to API, and strings is util package for strings.When we are done with imports, it is time to create a structure for storing a response from API. As API returns a json array of results, we will declare the Result structure.

type Result struct {
	Answer   string `json:"answer"`
	Link     string `json:"link"`
	Sentence string `json:"sentence"`
}

func (rr Result) String() string {
	return fmt.Sprintf("Answer (%s) | Link (%s) | Sentence (%s)", rr.Answer, rr.Link, rr.Sentence)
}

We also implement the String function (part of Stringers interface), for easier printing of the Result objects.

When we are finished with preparation, it’s time to implement the core function. To pass the question to the API call we need to create a json string and create a Reader object from it. Then we will create a request object and pass the Reader object and API url. Also we need to add Content-Type to the request header.

url := "https://api.yottaanswers.com/api/v1/publicQuestion"

requestData := make(map[string]string)
requestData["question"] = "What is golang"
requestJson, _ := json.Marshal(requestData)
payload := strings.NewReader(string(requestJson))

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Content-Type", "application/json")

After that we call the request using the Default client and, if there is no error, we read the body of the response. In this code body of the response is a Reader object, and we need to close it. And transfer the body object to an array of Results.

res, err := http.DefaultClient.Do(req)
if err != nil {
	fmt.Println(err)
	return
}
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)

var results []Result
json.Unmarshal(body, &results)

At the end we will just print answers.

fmt.Printf("Question %s\n", question)
for ind, r := range results {
	fmt.Println(ind, r)
}

For example, for a question “What is Golang?”, output would be:

Question What is Golang?
0 Answer (a statically typed, garbage collected and compiled programming language)
1 Answer (cross platform language that builds a single binary with all libraries bundled in and can use all of your CPU cores with ease)
2 Answer (a new open source programming language )
3 Answer (a free and open-source programming language)
4 Answer (The application )
5 Answer (which is a statically compiled language)
6 Answer (my go to language for all the new microservices I write)
7 Answer (very fast programming language)
8 Answer (a good programming language)
9 Answer (a compiled and concurrent Open Source programming language )

Code for Private version

There is not much difference between codes for both versions of API. If you want to call the Private version, you only need to change the end of the url to privateQuestion and to add to the header your API key.

req.Header.Add("Authorization","Bearerey <YOUR API KEY>")

Full Code

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

type Result struct {
	Answer   string `json:"answer"`
	Link     string `json:"link"`
	Sentence string `json:"sentence"`
}

func (rr Result) String() string {
	return fmt.Sprintf("Answer (%s)", rr.Answer)
}

func ApiPublic(question string) {

	url := "https://api.yottaanswers.com/api/v1/publicQuestion"

	requestData := make(map[string]string)
	requestData["question"] = question
	requestJson, _ := json.Marshal(requestData)
	payload := strings.NewReader(string(requestJson))

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}

	body, _ := ioutil.ReadAll(res.Body)
	res.Body.Close()

	var results []Result
	json.Unmarshal(body, &results)

	fmt.Printf("Question %s\n", question)
	for ind, r := range results {
		fmt.Println(ind, r)
	}

}

Summery

In this post, we looked at how to create a simple answering system using YottaAnswers API. This API is a very simple and very powerful tool for every developer interested. I believe that there are endless possibilities with this API, but this should be a great start in your journey.

This is it for now. Thank you for reading. I hope this post was useful for giving you some idea of what you could do with API. Feel free to share your thoughts and ideas in the comments.


Leave a Reply

Required fields are marked *