0

I'm very new to Go so hopefully this is simple to fix. I want to build a JSON value from rows in an SQL database. It doesn't have to be SQL but I'm looking for a way to generate a list of structs or a container that holds many values in order to generate JSON from it.

For example, an HTTP GET request to "/post" would return:

{
  "posts": [
    { "title": "First title", "created_by": "User1" },
    { "title": "My second post", "created_by": "User1"}
  ]
}

I don't know what's the proper way to do this. I've tried other ways using an array of pointers but it doesn't come out correctly. So far it prints out the correct values for each struct but the resulting Marshal is empty [{},{},{}]

Please go easy on me :)

example.go

package main

import (
    "fmt"
    "encoding/json"
    "time"
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)


type Post struct {
    name string `json:"name"`
    created_by string `json:"created_by"`
    created_at time.Time `json:"created_at"`
}

type Posts []Post

func main() {

    db, err := sql.Open("mysql", "root:1234@/blog?parseTime=true")
    if err != nil { panic(err.Error()) }
    defer db.Close()

    err = db.Ping()
    if err != nil { panic(err.Error()) }

    rows, err := db.Query("select title, created_by, created_at from post")
    if err != nil { panic(err.Error()) }
    defer rows.Close()

    var posts Posts
    for rows.Next() {            
        var post Post
        err := rows.Scan(&post.name, &post.created_by, &post.created_at)
        if err != nil { panic(err.Error()) }
        fmt.Printf("name=%s, created_by=%s, created_at=%s\n", post.name, post.created_by, post.created_at)
        posts = append(posts, post)                  
    }    

    data, err := json.Marshal(posts)    
    if err != nil { panic(err.Error()) }
    fmt.Printf("%s\n", data)
}
1
  • I just tried to Marshal a single Post and that doesn't work either. I'm missing something. Commented Mar 2, 2016 at 17:19

1 Answer 1

1

Your fields aren't exported, so the json package can't see them.

See 50 Shades of Go for a longer explanation and others common gotchas.

Sign up to request clarification or add additional context in comments.

3 Comments

Well, an unexported field is the private equivalent of other languages, so it is absolutely normal another package can't see it. It would defy the definition of private attribute otherwise…
I was referring to using style (Capitalization) to change behavior rather than a keyword (private like you said) or a symbol (Nim language uses *). Just something to figure out when learning a new language :)
Well… not adding a keyword or symbol to denote private state is shorter to write, faster to read, and in the end simpler. That may be the best example of "Convention over configuration".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.