Go Language REST API Part -2

In this article, we'll build a RESTful API in Go language that allows us to perform CRUD (Create, Read, Update, and Delete) operations using all HTTP verbs. We'll use the Gorilla Mux package to handle our routing.

Setting up the Project

Before we start, make sure you have Go installed on your system. You can download the latest version of Go from the official website golang.org/dl.

To create a new Go project, create a new directory for your project and navigate to it in the terminal. We'll call our project rest-api. Inside the rest-api directory, create a new file called main.go.

Next, we'll install the Gorilla Mux package using the following command:

go get -u github.com/gorilla/mux

This will install the package in the $GOPATH directory.

Defining our Data Model

In our REST API, we'll be working with a simple data model representing a book. Each book has an ID, title, author, and description. We'll define a struct to represent a book as follows:

type Book struct {
    ID          string `json:"id"`
    Title       string `json:"title"`
    Author      string `json:"author"`
    Description string `json:"description"`
}

We'll also create a global variable to store our books:

var books []Book

Implementing the Endpoints

GET /books

The first endpoint we'll implement is a GET endpoint that retrieves all the books. The endpoint will respond with a JSON array of all the books.

func getBooks(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(books)
}

GET /books/{id}

The second endpoint we'll implement is a GET endpoint that retrieves a specific book by its ID. The endpoint will respond with a JSON object representing the book.

func getBook(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    params := mux.Vars(r)
    for _, item := range books {
        if item.ID == params["id"] {
            json.NewEncoder(w).Encode(item)
            return
        }
    }
    json.NewEncoder(w).Encode(&Book{})
}

POST /books

The third endpoint we'll implement is a POST endpoint that creates a new book. The endpoint will accept a JSON object representing the book, generate a new ID for the book, and add it to the list of books.

func createBook(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    var book Book
    _ = json.NewDecoder(r.Body).Decode(&book)
    book.ID = strconv.Itoa(rand.Intn(1000000))
    books = append(books, book)
    json.NewEncoder(w).Encode(book)
}

PUT /books/{id}

The PUT method is used to update an existing resource. In this case, we will be updating a book's information using its ID as a parameter. Here's an example:

func updateBook(w http.ResponseWriter, r *http.Request) {
    // Get the book ID from the URL parameter
    params := mux.Vars(r)
    id := params["id"]

    // Check if the book exists
    book, err := getBookByID(id)
    if err != nil {
        w.WriteHeader(http.StatusNotFound)
        return
    }

    // Parse the request body to get the new book information
    var updatedBook Book
    err = json.NewDecoder(r.Body).Decode(&updatedBook)
    if err != nil {
        w.WriteHeader(http.StatusBadRequest)
        return
    }

    // Update the book with the new information
    book.Title = updatedBook.Title
    book.Author = updatedBook.Author
    book.Year = updatedBook.Year

    // Save the updated book to the database
    err = updateBookInDB(book)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    w.WriteHeader(http.StatusOK)
}

This function first gets the book ID from the URL parameter using mux.Vars(). It then checks if the book exists using the getBookByID() function, which retrieves a book from the database by its ID. If the book does not exist, it returns a 404 status code.

The function then parses the request body to get the new book information using json.NewDecoder(). If the request body is malformed, it returns a 400 status code.

The book's information is updated with the new information from the request body, and it is saved to the database using updateBookInDB(). If there is an error while updating the book, it returns a 500 status code.

Finally, it returns a 200 status code to indicate that the book was successfully updated.

DELETE /books/{id}

The DELETE method is used to delete an existing resource. In this case, we will be deleting a book using its ID as a parameter. Here's an example:

func deleteBook(w http.ResponseWriter, r *http.Request) {
    // Get the book ID from the URL parameter
    params := mux.Vars(r)
    id := params["id"]

    // Check if the book exists
    book, err := getBookByID(id)
    if err != nil {
        w.WriteHeader(http.StatusNotFound)
        return
    }

    // Delete the book from the database
    err = deleteBookFromDB(book)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    w.WriteHeader(http.StatusNoContent)
}

This function first gets the book ID from the URL parameter using mux.Vars(). It then checks if the book exists using the getBookByID() function. If the book does not exist, it returns a 404 status code.

The function then deletes the book from the database using deleteBookFromDB(). If there is an error while deleting the book, it returns a 500 status code.

Finally, it returns a 204 status code to indicate that the book was successfully deleted.

I hope this helps, you!!

More such articles:

https://medium.com/techwasti

https://www.youtube.com/channel/UCiTaHm1AYqMS4F4L9zyO7qA

https://www.techwasti.com/

\==========================**=========================

If this article adds any value to you then please clap and comment.

Let’s connect on Stackoverflow, LinkedIn, & Twitter.

Did you find this article valuable?

Support techwasti by becoming a sponsor. Any amount is appreciated!