title: Doing an update to a database with partial data in Go
body: <p>So I have the following function in an API:</p>
  <pre><code>type Product struct {
      Id          int32             `json:&quot;id&quot; db:&quot;id&quot;`
      CompanyId   int32             `json:&quot;companyID&quot; db:&quot;company_id&quot;`
      Name        *string           `json:&quot;name&quot; db:&quot;name&quot;`
      Description *string           `json:&quot;description&quot; db:&quot;description&quot;`
      ExternalId  *string           `json:&quot;externalID&quot; db:&quot;external_id&quot;`
      Tags        types.StringArray `json:&quot;tags&quot; db:&quot;tags&quot;`
      Enabled     bool              `json:&quot;enabled&quot; db:&quot;enabled&quot;`
      CreatedAt   time.Time         `json:&quot;createdAt&quot;`
      UpdatedAt   time.Time         `json:&quot;updatedAt&quot;`
  }
  
  func updateProduct(event UpdateProductEvent) (Response, error) {
  // TODO - determine how we want to log. fmt jsut does prints. The log package?
  fmt.Println(&quot;This is updateProduct&quot;)
  
  var id int64
  
  err := db.QueryRow(`
      UPDATE 
          v2.products 
      SET 
          company_id = $2, 
          name = $3, 
          description = $4, 
          external_id = $5, 
          enabled = $6
      WHERE id = $1 RETURNING id`,
      Product.Id,
      Product.CompanyId,
      Product.Name,
      Product.Description,
      Product.ExternalId,
      Product.Enabled,
  ).Scan(&amp;id)
  if err != nil {
      fmt.Println(&quot;Error updating product: &quot; + err.Error())
      fmt.Println(&quot;Product: &quot;)
      return Response{}, errors.New(&quot;Error inserting product&quot;)
  }
  
  return Response{
      Id: 8,
  }, nil
  }
  </code></pre>
  <p>So a Product gets passed in and then I need to update the entity in the database. The above works fine in the case where I get a full product passed in. But for this API that might not be the case, it could only be a partial one.</p>
  <p>So I might only have two fields in the JSON passed to the API.</p>
  <p>So what I'm thinking is passing in an interface{}, instead of the Product so I dont get zero values for fields not set. Then looping through interface{} to get the fields. From those fields I would check if that field exists on the Product object. If it does get the tag from the field, this would be the appropriate column in the database, and then create the query string for the QueryRow call and add all the fields to an interface{} array and let that be the second param. Something like:</p>
  <pre><code>func updateProduct(event interface{}) (Response, error) {
  var values []interface{}
  // Loop through the event and get the field and value
  for field, i := range event.fields {
      if Product.Has(field.name) {
          //add db tag of Product field to query 
          values = append(values, field.value)
      }
  }
  
  err := db.QueryRow(`
      UPDATE 
          v2.products 
      SET 
          //fields from the loop above as needed
      WHERE id = $1 RETURNING id`,
      values...,
  ).Scan(&amp;id)
  
  ...
  }
  </code></pre>
  <p>I think i can get this, or something like it, to work but it seems like a very round about way to do something very common. I just cant think of any other way to do it.So is there a more common/simpler approach that I'm missing. I cant find anything Googling either.</p>
  <p>EDIT: In my haste and attempt to simplfy I left out an important part. This is for an AWS Lambda. So the object passed into updateProduct depends on what comes from the API Gateway. So if i make it the UpdateProductEvent it will parse the json into the object, in this case the Product. If I just make it an interface{} it will basically just make a map.</p>
  <p>So if my request is</p>
  <pre><code>{
      &quot;product&quot;: {
          &quot;name&quot;: &quot;Test17&quot;,
          &quot;externalID&quot;: &quot;test17&quot;,
          &quot;description&quot;: &quot;&quot;,
          &quot;companyID&quot;: 309
      }
  }
  </code></pre>
  <p>The first method, setting an explicit object, it will create a Product and fields not in the json will have the 0 value for their field.</p>
  <p>If i make it an interface it will be an object with those properties and not the zero values for the rest of the fields in Product</p>