title: How correctly use UUID4 in Golang application?
body: <p>I am new in <code>Golang</code> and need some help! I have several questions.</p>
  
  <p>In <code>PostgreSQL</code> database I have table called <code>surveys</code>.</p>
  
  <pre><code>CREATE TABLE SURVEYS(
    SURVEY_ID UUID PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),
    SURVEY_NAME VARCHAR NOT NULL,
    SURVEY_DESCRIPTION TEXT,
    START_PERIOD TIMESTAMP,
    END_PERIOD TIMESTAMP
  );
  </code></pre>
  
  <p>As you can see <code>SURVEY_ID</code> column is <code>PRIMARY KEY</code> and it's type is <code>UUID4</code>.</p>
  
  <p>In <code>Golang</code> application I create such <code>struct</code> to this table:</p>
  
  <pre><code>type Survey struct {
      ID string `json:"survey_id"`
      Name string `json:"survey_name"`
      Description utils.NullString `json:"survey_description"`
      StartPeriod utils.NullTime `json:"start_period"`
      EndPeriod utils.NullTime `json:"end_period"`
  }
  </code></pre>
  
  <p>As you can see type of ID field is <code>string</code>. Is it correct? I am not sure that it's best practice.</p>
  
  <p>My second question about strange result which I have when make <code>GET</code> request to specific survey by it's ID.</p>
  
  <p>For example when I make such request:</p>
  
  <pre><code>http://localhost:8000/api/survey/0cf1cf18-d5fd-474e-a8be-754fbdc89720
  </code></pre>
  
  <p>As response I have this:</p>
  
  <pre><code>{
      "survey_id": "0cf1cf18-d5fd-474e-a8be-754fbdc89720",
      "survey_name": "NAME",
      "survey_description": {
          "String": "DESCRIPTION",
          "Valid": true
      },
      "start_period": {
          "Time": "2019-01-01T00:00:00Z",
          "Valid": false
      },
      "end_period": {
          "Time": "0001-01-01T00:00:00Z",
          "Valid": false
      }
  }
  </code></pre>
  
  <p>As you can see something wrong with last 3 field: <code>survey_description</code>, <code>start_period</code> and <code>end_period</code>. I want to see key and value in one line. For example as here:</p>
  
  <pre><code>{
      "survey_id": "0cf1cf18-d5fd-474e-a8be-754fbdc89720",
      "survey_name": "NAME",
      "survey_description": "DESCRIPTION",
      "start_period": "2019-01-01 00:00:00",
      "end_period": null
  }
  </code></pre>
  
  <p>Where exactly I make mistake in my code?</p>
  
  <p><strong>utils.go:</strong></p>
  
  <pre><code>package utils
  
  import (
      "database/sql"
      "encoding/json"
      "fmt"
      "github.com/lib/pq"
      "time"
  )
  
  // NullTime is an alias for pq.NullTime data type.
  type NullTime struct {
      pq.NullTime
  }
  
  // MarshalJSON for NullTime.
  func (nt *NullTime) MarshalJSON() ([]byte, error) {
      if !nt.Valid {
          return []byte("null"), nil
      }
      val := fmt.Sprintf("\"%s\"", nt.Time.Format(time.RFC3339))
      return []byte(val), nil
  }
  
  // UnmarshalJSON for NullTime.
  func (nt *NullTime) UnmarshalJSON(b []byte) error {
      err := json.Unmarshal(b, &amp;nt.Time)
      nt.Valid = err == nil
      return err
  }
  
  // NullInt64 is an alias for sql.NullInt64 data type.
  type NullInt64 struct {
      sql.NullInt64
  }
  
  // MarshalJSON for NullInt64.
  func (ni *NullInt64) MarshalJSON() ([]byte, error) {
      if !ni.Valid {
          return []byte("null"), nil
      }
      return json.Marshal(ni.Int64)
  }
  
  // UnmarshalJSON for NullInt64.
  func (ni *NullInt64) UnmarshalJSON(b []byte) error {
      err := json.Unmarshal(b, &amp;ni.Int64)
      ni.Valid = err == nil
      return err
  }
  
  // NullString is an alias for sql.NullString data type.
  type NullString struct {
      sql.NullString
  }
  
  // MarshalJSON for NullString.
  func (ns *NullString) MarshalJSON() ([]byte, error) {
      if !ns.Valid {
          return []byte("null"), nil
      }
      return json.Marshal(ns.String)
  }
  
  // UnmarshalJSON for NullString.
  func (ns *NullString) UnmarshalJSON(b []byte) error {
      err := json.Unmarshal(b, &amp;ns.String)
      ns.Valid = err == nil
      return err
  }
  </code></pre>
  
  <p><strong>routes.go:</strong></p>
  
  <pre><code>router.HandleFunc("/api/survey/{survey_id:[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}}", controllers.GetSurvey).Methods("GET")
  </code></pre>
  
  <p><strong>controllers/survey.go:</strong></p>
  
  <pre><code>var GetSurvey = func(responseWriter http.ResponseWriter, request *http.Request) {
      // Initialize variables.
      survey := models.Survey{}
      var err error
  
      vars := mux.Vars(request)
  
      // Execute SQL statement.
      err = database.DB.QueryRow("SELECT * FROM surveys WHERE survey_id = $1;", vars["survey_id"]).Scan(&amp;survey.ID, &amp;survey.Name, &amp;survey.Description, &amp;survey.StartPeriod, &amp;survey.EndPeriod)
  
      // Shape the response depending on the result of the previous command.
      if err != nil {
          log.Println(err)
          switch err {
          case sql.ErrNoRows:
              utils.ResponseWithError(responseWriter, http.StatusNotFound, "The entry not found.")
          default:
              utils.ResponseWithError(responseWriter, http.StatusInternalServerError, err.Error())
          }
          return
      }
      utils.Response(responseWriter, http.StatusOK, survey)
  }
  </code></pre>