The Concept of REST API

Understand the basic concept of REST API in this lesson.

Introduction to REST API

API stands for Application Programming Interface. Web applications usually use APIs to communicate with other web applications. An API shares resources or data that can be accessed by a specific URL or request. By using HTTP, APIs can be used by many applications, including mobile and web applications. There are many APIs with different functionalities, like retrieving resources about weather conditions, a list of cities in a specific country, and even for complex tasks like converting speech data into text.

An API is typically used by web applications via REST API, a mechanism used to communicate between the client and the server. A REST API can be implemented by many programming languages through formats like XML, JSON, and more. The JSON format is commonly used when working with REST APIs.

REST API application example

To understand how a REST API application works, we’ll take a look at how a simple one is created. Before creating requests, we’ll run the application by clicking the “Run” button. Then we’ll open a new terminal tab by clicking the “+” button.

After the new terminal tab is opened, we’ll try to make the following requests:

  1. Create a GET request using cURL or other tools like Postman.
  curl -XGET -H "Content-type: application/json" 'https://6ej3lygmelmwy.educative.run/books'

NOte: Make sure the URL matches the URL used to run the server.

This is the output if the request succeeds.

[
  {
    "Id": 1,
    "Title": "Programming with Go"
  },
  {
    "Id": 2,
    "Title": "Introduction to MySQL"
  },
  {
    "Id": 3,
    "Title": "Microservice Architecture"
  }
]
  1. Create a POST request using cURL or other tools like Postman.
  curl -XPOST -H "Content-type: application/json" -d '{"id":6,"title":"My New Book"}' 'https://6ej3lygmelmwy.educative.run/books/create'

Note: Make sure the URL matches the URL used to run the server.

This is the output if the request succeeds.

{"Id":6,"Title":"My New Book"}

The complete simple REST API application can be seen below:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

// create a book type
type Book struct {
	Id    int
	Title string
}

// create a books data
var books []Book = []Book{
	{
		Id:    1,
		Title: "Programming with Go",
	},
	{
		Id:    2,
		Title: "Introduction to MySQL",
	},
	{
		Id:    3,
		Title: "Microservice Architecture",
	},
}

func main() {
	// create a mux to handle the requests
	var mux *http.ServeMux = http.NewServeMux()

	// register handlers to mux
	mux.HandleFunc("/books", getAllBooks)
	mux.HandleFunc("/books/create", createBook)

	// create the server with the mux as a handler
	var server *http.Server = &http.Server{
		Addr:    ":3000",
		Handler: mux,
	}

	fmt.Println("Starting server on port 3000")

	// start the server
	if err := server.ListenAndServe(); err != nil {
		log.Panic(err)
	}
}

// getAllBooks returns all books data
func getAllBooks(w http.ResponseWriter, r *http.Request) {
	// convert "books" into JSON format
	output, err := json.Marshal(books)
	if err != nil {
		log.Panic(err)
	}

	// set the response header
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)

	// set the response body
	_, err = w.Write(output)
	if err != nil {
		log.Panic(err)
	}
}

// createBook returns the recently created book
func createBook(w http.ResponseWriter, r *http.Request) {
	// check the request method
	if r.Method != http.MethodPost {
		// if the request method is not "POST"
		// this response is returned
		w.WriteHeader(http.StatusMethodNotAllowed)
		_, err := w.Write([]byte("method not allowed"))
		if err != nil {
			log.Panic(err)
		}
		return
	}

	// create a variable to store the request body for book data
	var newBook Book

	// decode the request body
	err := json.NewDecoder(r.Body).Decode(&newBook)
	if err != nil {
		log.Panic(err)
	}

	// add a new book
	books = append(books, newBook)

	// convert the recently added book data into the JSON format
	output, err := json.Marshal(newBook)
	if err != nil {
		log.Panic(err)
	}

	// set the response header
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)

	// set the response body
	_, err = w.Write(output)
	if err != nil {
		log.Panic(err)
	}
}
Simple API Application

As seen in the code above, the server mux is created to handle the requests based on the routes. For example, the /books route uses the getAllBooks handler to get the data of all books. Then the handlers are registered into the server mux. After the server mux is configured, the HTTP server is created with the server mux. The HTTP server is started in port 3000 because the address configuration of the server is ":3000".

The following two handlers are used in this server:

  • getAllBooks is used to get all the book data. The books variable is converted into JSON format. Then, the response headers and body are configured. The body of the response is the data of all books that are converted into JSON format.

  • createBook is used to create a new book data. Inside the handler, the request method is checked. If the check succeeds, the request body is decoded using the json package and the new book data is added. After the new book is added, the response is sent to the client. The response body is the book that was recently added.