Go Lang and PostgreSQL Web App MVC Pattern Part 5

Have a Database Problem? Speak with an Expert for Free
Get Started >>

Introduction

This is part five of a tutorial series explaining how to create a Go Lang and PostgreSQL Web App with MVC pattern. The previous section of this series covered how to retrieve a single record in PostgreSQL using Golang with a MVC pattern. This part five will explain how to insert a record in PostgreSQL using Golang via the MVC pattern.

Prerequisite

  • Possess a solid command of the first four parts of this tutorial series explaining how to create a Go Lang and PostgreSQL Web App with MVC pattern.

Inserting a Record in PostgreSQL using Go Lang

First, a record must be inserted into the PostgreSQL database. However, the main.go file must first be updated to allow this operation by executing the following code:

1
2
3
4
5
6
7
8
http.HandleFunc("/", index)
http.HandleFunc("/list", model.PatientIndex)
http.HandleFunc("/patient/show", model.PatientShow)

http.HandleFunc("/patient/create", model.PatientCreate)
http.HandleFunc("/patient/create/process", model.PatientCreateProcess)

http.ListenAndServe(":8080", nil)
  • Note that two scripts were added that will handle the request for adding the patient’s info using a form http.HandleFunc("/patient/create", model.Create); this is the actual process of inserting the record from the form http.HandleFunc("/patient/create/process", model.CreateProcess).

Controller for Inserting a Record in PostgreSQL using Go Lang

  • As in the previous section of this tutorial, a controller will be created against the two additional request handlers that were created in the previous section.

  • A new function will now be created in the handler.go file named PatientCreate() with the folowing code:

1
2
3
func PatientCreate(w http.ResponseWriter, r *http.Request) {
    config.TPL.ExecuteTemplate(w, "createForm.gohtml", nil)
}

The above code simply serves as a template file called createForm.gohtml. This file will serve as a form to gather the patient’s details.

Now execute the following code to create the other function called PatientCreateProcess():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func PatientCreateProcess(w http.ResponseWriter, r *http.Request) {
    if r.Method != "POST" {
        http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
        return
    }

    patient, err := InsertPatient(r)
    if err != nil {
        http.Error(w, http.StatusText(406), http.StatusNotAcceptable)
        return
    }

    config.TPL.ExecuteTemplate(w, "createdPatient.gohtml", patient)
}
  • The above code will call the function for inserting the record InsertPatient(r). It will then capture the details and store records to patient object. It will also pass those values to the template createdPatient.gohtml that will be displayed for review purposes.

Configuring Model for Inserting Record in PostgreSQL using Go Lang

This section will explain how to create the model that will process the logic for performing the INSERT operation against the PostgreSQL database. To do this, modify the models.go file as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func InsertPatient(r *http.Request) (Patient, error) {
    // get form values
    p := Patient{}
    p.Patient_id = r.FormValue("patientID")
    p.Name = r.FormValue("name")
    p.Lastname = r.FormValue("lastname")
    p.Gender = r.FormValue("gender")
    pID := r.FormValue("age")
    // converts string to integer
    age, err := strconv.Atoi(pID)
    p.Age = age
    // validate form values
    if p.Patient_id == "" || p.Name == "" || p.Lastname == "" || p.Gender == "" || pID == "" {
        return p, errors.New("400. Bad request. All fields must be complete.")
    }

    // insert values
    _, err = config.DB.Exec("INSERT INTO tbl_patientinfo (patient_id, name, lastname, gender, age) VALUES ($1, $2, $3, $4, $5)", p.Patient_id, p.Name, p.Lastname, p.Gender, p.Age)
    if err != nil {
        return p, errors.New("500. Internal Server Error." + err.Error())
    }
    return p, nil
}

Following is a breakdown of the above function:

  • The code obtains the form values and assign the values to the Patient slice.
  • A basic validation is performed.
  • The INSERT operation is performed with the aid of config.DB.Exec() method.
  • The value of the slice, which is p, is returned and processed as needed.

Configuring the front-end

This section will cover how to create templates as needed for application.

  • First, the createForm.gohtml template must be created for a user to input the patient details, as shown here:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html>

    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Add Patient Details</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    </head>
    <body>
        <!--[if lt IE 7]>
           <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
       <![endif]-->


<div class="container mt-4" >
<h1>Add Patient</h1>

<form method="post" action="/patient/create/process">
  <div class="form-group">
    <label for="patienID">Patient ID</label>
    <input type="text" class="form-control" name="patientID" id="patientID" placeholder="Patient ID">
  </div>
  <div class="form-group">
    <label for="name">Patient's Name</label>
    <input type="text" class="form-control" name="name" id="name" placeholder="Patient' s Name">
  </div>
  <div class="form-group">
    <label for="name">Patient's LastName</label>
    <input type="text" class="form-control" name="lastname" id="lastname" placeholder="Patient' s LastName">
  </div>
  <div class="form-group">
    <label for="name">Patient's Gender</label>
    <input type="text" class="form-control" name="gender" id="gender" placeholder="Patient' s Gender">
  </div>
  <div class="form-group">
    <label for="name">Patient's Age</label>
    <input type="text" class="form-control" name="age" id="age" placeholder="Patient' s Age">
  </div>
  <a class="action btn btn-primary" href="">Save</a>
  <a class="action btn btn-primary" href="/">Cancel</a>
</form>
</div>
        <script src="" async defer></script>
    </body>
</html>

The above structure should resemble the following:

  • Next, a template that will show the values that were created in the previous form must be set up. This is the createdForm.gohtml and executed as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Patient Information</title>
    <link
     rel="stylesheet"
     href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
     integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
     crossorigin="anonymous"
   />
    <script
     src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
     integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
     crossorigin="anonymous"
   ></script>
  </head>
  <body>
    <div class="container mb-6">
      <form class="mt-5">
        <h2>Patient's Information</h2>
        <div class="form-group row">
          <label for="name" class="col-sm-2 col-form-label">Name</label>
          <div class="col-sm-10">
            <input
             type="text"
             class="form-control"
             id="name"
             value="{{.Name}} {{.Lastname}}"
             disabled
           />
          </div>
        </div>
        <div class="form-group row">
          <label for="gender" class="col-sm-2 col-form-label">Gender</label>
          <div class="col-sm-10">
            <input
             type="text"
             class="form-control"
             id="gender"
             value="{{.Gender}}"
             disabled
           />
          </div>
        </div>
        <div class="form-group row">
          <label for="age" class="col-sm-2 col-form-label">Age</label>
          <div class="col-sm-10">
            <input
             type="text"
             class="form-control"
             id="age"
             value="{{.Age}}"
             disabled
           />
          </div>
        </div>

        <div class="form-group row">
          <div class="col-sm-10 offset-sm-2">
            <a class="btn btn-primary" href="/"> « Patient Listing</a>
          </div>
        </div>
      </form>
    </div>
  </body>
</html>

With all the necessary files and configurations created, now test the application by inserting a new record into the database by following the usual steps to run projects. Now perform the INSERT operation via a browser as follows:

Conclusion

This was part five of the tutorial series explaining how to create a Go Lang and PostgreSQL Web App with MVC pattern. This article explained how to perform the insert operation against PostgreSQL using Go Lang with MVC pattern. The tutorial specifically covered how to insert a record in PostgreSQL with Golang, how to create a controller for inserting a record, how to configure the model for inserting record in PostgreSQL using Golang and how to configure the front end of the application. Remember that the main.go file must be updated before a record can be inserted into the PostgreSQL database.

The Code

Below is the code of the files that we used in this application.

The main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main

import (
    "html/template"
    "net/http"
    "patientinfo/model"

    _ "github.com/lib/pq"
)

// package level scope, which means it can be access anywhere in this packager.
var tpl *template.Template

func main() {
http.HandleFunc("/", index)
http.HandleFunc("/list", model.PatientIndex)
http.HandleFunc("/patient/show", model.PatientShow)

http.HandleFunc("/patient/create", model.PatientCreate)
http.HandleFunc("/patient/create/process", model.PatientCreateProcess)

http.ListenAndServe(":8080", nil)
}

func index(w http.ResponseWriter, r *http.Request) {
    http.Redirect(w, r, "/list", http.StatusSeeOther)
}

The createForm.gohtml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html>

    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Add Patient Details</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    </head>
    <body>
        <!--[if lt IE 7]>
           <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
       <![endif]-->


<div class="container mt-4" >
<h1>Add Patient</h1>

<form method="post" action="/patient/create/process">
  <div class="form-group">
    <label for="patienID">Patient ID</label>
    <input type="text" class="form-control" name="patientID" id="patientID" placeholder="Patient ID">
  </div>
  <div class="form-group">
    <label for="name">Patient's Name</label>
    <input type="text" class="form-control" name="name" id="name" placeholder="Patient's Name">
  </div>
  <div class="form-group">
    <label for="name">Patient's LastName</label>
    <input type="text" class="form-control" name="lastname" id="lastname" placeholder="Patient's LastName">
  </div>
  <div class="form-group">
    <label for="name">Patient's Gender</label>
    <input type="text" class="form-control" name="gender" id="gender" placeholder="Patient's Gender">
  </div>
  <div class="form-group">
    <label for="name">Patient's Age</label>
    <input type="text" class="form-control" name="age" id="age" placeholder="Patient's Age">
  </div>
  <input class="btn btn-primary" type="submit">
  <a class="action btn btn-primary" href="/">Cancel</a>
</form>
</div>
        <script src="" async defer></script>
    </body>
</html>

The createdPatient.gohtml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Patient Information</title>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
      integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
      crossorigin="anonymous"
    />
    <script
      src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
      crossorigin="anonymous"
    ></script>
  </head>
  <body>
    <div class="container mb-6">
      <form class="mt-5">
        <h2>Patient's Information</h2>
        <div class="form-group row">
          <label for="name" class="col-sm-2 col-form-label">Name</label>
          <div class="col-sm-10">
            <input
              type="text"
              class="form-control"
              id="name"
              value="{{.Name}} {{.Lastname}}"
              disabled
            />
          </div>
        </div>
        <div class="form-group row">
          <label for="gender" class="col-sm-2 col-form-label">Gender</label>
          <div class="col-sm-10">
            <input
              type="text"
              class="form-control"
              id="gender"
              value="{{.Gender}}"
              disabled
            />
          </div>
        </div>
        <div class="form-group row">
          <label for="age" class="col-sm-2 col-form-label">Age</label>
          <div class="col-sm-10">
            <input
              type="text"
              class="form-control"
              id="age"
              value="{{.Age}}"
              disabled
            />
          </div>
        </div>

        <div class="form-group row">
          <div class="col-sm-10 offset-sm-2">
            <a class="btn btn-primary" href="/"> « Patient Listing</a>
          </div>
        </div>
      </form>
    </div>
  </body>
</html>

The models.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func InsertPatient(r *http.Request) (Patient, error) {
    // get form values
    p := Patient{}
    p.Patient_id = r.FormValue("patientID")
    p.Name = r.FormValue("name")
    p.Lastname = r.FormValue("lastname")
    p.Gender = r.FormValue("gender")
    pID := r.FormValue("age")
    age, err := strconv.Atoi(pID)
    p.Age = age
    // validate form values
    if p.Patient_id == "" || p.Name == "" || p.Lastname == "" || p.Gender == "" || pID == "" {
        return p, errors.New("400. Bad request. All fields must be complete.")
    }

    // insert values
    _, err = config.DB.Exec("INSERT INTO tbl_patientinfo (patient_id, name, lastname, gender, age) VALUES ($1, $2, $3, $4, $5)", p.Patient_id, p.Name, p.Lastname, p.Gender, p.Age)
    if err != nil {
        return p, errors.New("500. Internal Server Error." + err.Error())
    }
    return p, nil
}

The handler.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func PatientCreateProcess(w http.ResponseWriter, r *http.Request) {
    if r.Method != "POST" {
        http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
        return
    }

    patient, err := InsertPatient(r)
    if err != nil {
        http.Error(w, http.StatusText(406), http.StatusNotAcceptable)
        return
    }

    config.TPL.ExecuteTemplate(w, "createdPatient.gohtml", patient)
}

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.