REST (Representational State Transfer) is the most used interface to populate the dynamic data and perform operations such as add, update and delete in web applications. The REST APIs are used in all kinds applications to make GET, POST, PUT or DELETE HTTP requests to perform CRUD operations on data.
In this tutorial, we are going to explain to create simple REST API with Golang to perform GET, POST, DELETE and PUT on dynamic data. We will mainly focus on the basic concepts of this, so we will perform actions on employee JSON data instead of database. So you can use this by connection with database as per your application requirement.
1. Create Server to Handle API Requests
We need to create server to handle HTTP requests to the API. So we will create a function apiRequests()
in main.go
file and called within func main()
. The function apiRequests()
will handle all requests to the root URL.
package main import ( "fmt" "log" "net/http" ) func homePage(w http.ResponseWriter, r *http.Request){ fmt.Fprintf(w, "Welcome to the API Home page!") } func apiRequests() { http.HandleFunc("/", homePage) log.Fatal(http.ListenAndServe(":3000", nil)) } func main() { apiRequests() }
When we run the above code, the API will start on post 3000. The URL http://localhost:3000/
will be loaded on browser and see the API home page welcome message and it means we have created the base of our REST API.
2. Create Employee Dummy Data for REST API
In this tutorial we will create simple REST API to perform CRUD operations GET, POST, DELETE and PUT
employee data. We will create some dummy employee data in func main()
. We will perform
func main() { Employees = []Employee{ Employee{Id: "1", Name: "Jhon Smith", Address: "New Jersy USA", Salary: "20000"}, Employee{Id: "2", Name: "William", Address: "Wellington Newziland", Salary: "12000"}, Employee{Id: "3", Name: "Adam", Address: "London England", Salary: "15000"}, } }
3. Get All Employee
Now we will start implementing our REST API methods. We will implement function getAllEmployees()
to get all employee data.
func getAllEmployees(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(Employees) }
We will also handle routing and call function getAllEmployees()
on action employees
to get all employee in JSON format. We will use gorilla/mux
based HTTP router in place of the standard library and use in this tutorial example.
func apiRequests() { route := mux.NewRouter().StrictSlash(true) route.HandleFunc("/employees", getAllEmployees) log.Fatal(route.ListenAndServe(":3000", route)) }
When we load URL http://localhost:3000/employees
on method GET
then it will display all employee in JSON format.
{"Id":"1","Name":"Jhon Smith","Address":"New Jersy USA","Salary":"20000"}, {"Id":"2","Name":"William","Address":"Wellington Newziland","Salary":"12000"}, {"Id":"3","Name":"Adam","Address":"London England","Salary":"15000"}
We can also get the specific employee record by passing employee id. For this we will create function getEmployee()
to get employee data.
func getEmployee(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) key := vars["id"] for _, employee := range Employees { if employee.Id == key { json.NewEncoder(w).Encode(employee) } } }
we will call function getEmployee()
on route /employee/{id}
to get the employee by id.
func apiRequests() { route := mux.NewRouter().StrictSlash(true) route.HandleFunc("/employee/{id}", getEmployee) log.Fatal(http.ListenAndServe(":3000", route)) }
When we load URL http://localhost:3000/employee/3
then it will display employee by that id in JSON format.
{"Id":"3","Name":"Adam","Address":"London England","Salary":"15000"}
4. Create Employee Record
We will implement functionality to create a new employee record. We will create function createEmployee()
to add a new employee record.
func createEmployee(w http.ResponseWriter, r *http.Request) { reqBody, _ := ioutil.ReadAll(r.Body) var employee Employee json.Unmarshal(reqBody, &employee) Employees = append(Employees, employee) json.NewEncoder(w).Encode(employee) }
We will call function createEmployee()
on method POST
and route employee
to post employee details to add a new record.
func apiRequests() { route.HandleFunc("/employee", createEmployee).Methods("POST") log.Fatal(http.ListenAndServe(":3000", route)) }
When we run our API and POST
with following post body then it will create a new employee record.
{ "Id": "4", "Name": "Peter", "Address": "London, UK", "Salary": "40000" }
When we access URL with employee id 4 like http://localhost:3000/employee/4
then it will display employee by that id in JSON format.
{"Id":"4","Name":"Peter","Address":"London, UK","Salary":"40000"}
5. Delete Employee Record
We will implement employee delete functionality by creating function deleteEmployee()
to delete employee by id.
func deleteEmployee(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] for index, employee := range Employees { if employee.Id == id { Employees = append(Employees[:index], Employees[index+1:]...) } } }
We will call function deleteEmployee()
on route /employee/{id}
to delete employee.
func apiRequests() { route := mux.NewRouter().StrictSlash(true) route.HandleFunc("/employee/{id}", deleteEmployee).Methods("DELETE") log.Fatal(http.ListenAndServe(":3000", route)) }
When we will make HTTP request with method DELETE
to URL http://localhost:3000/employee/3
with employee id. It will delete that employee.
6. Complete REST API Code
Here is the complete running code for this example.
package main import ( "encoding/json" "fmt" "log" "io/ioutil" "net/http" "github.com/gorilla/mux" ) type Employee struct { Id string `json:"Id"` Name string `json:"Name"` Address string `json:"Address"` Salary string `json:"Salary"` } var Employees []Employee func homePage(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Welcome to the API Home page!") } func getAllEmployees(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(Employees) } func getEmployee(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) key := vars["id"] for _, employee := range Employees { if employee.Id == key { json.NewEncoder(w).Encode(employee) } } } func createEmployee(w http.ResponseWriter, r *http.Request) { reqBody, _ := ioutil.ReadAll(r.Body) var employee Employee json.Unmarshal(reqBody, &employee) Employees = append(Employees, employee) json.NewEncoder(w).Encode(employee) } func deleteEmployee(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] for index, employee := range Employees { if employee.Id == id { Employees = append(Employees[:index], Employees[index+1:]...) } } } func apiRequests() { route := mux.NewRouter().StrictSlash(true) route.HandleFunc("/", homePage) route.HandleFunc("/employees", getAllEmployees) route.HandleFunc("/employee", createEmployee).Methods("POST") route.HandleFunc("/employee/{id}", deleteEmployee).Methods("DELETE") route.HandleFunc("/employee/{id}", getEmployee) log.Fatal(http.ListenAndServe(":3000", route)) } func main() { Employees = []Employee{ Employee{Id: "1", Name: "Jhon Smith", Address: "New Jersy USA", Salary: "20000"}, Employee{Id: "2", Name: "William", Address: "Wellington Newziland", Salary: "12000"}, Employee{Id: "3", Name: "Adam", Address: "London England", Salary: "15000"}, } apiRequests() }
Conclusion
Here in this tutorial, we have implemented HTTP methods GET
, POST
and DELETE
to read, add and delete employee data. We have not implemented PUT
method to update employee data. You can try this at your end and share your suggestion if any regarding this.