Skip to content

Instantly share code, notes, and snippets.

@phalt
Created December 3, 2014 14:51
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save phalt/28d590eb916d5dca1a8f to your computer and use it in GitHub Desktop.
Save phalt/28d590eb916d5dca1a8f to your computer and use it in GitHub Desktop.
Simple HTTP API in Go
package main
import (
"github.com/gin-gonic/gin"
"database/sql"
"github.com/coopernurse/gorp"
_ "github.com/mattn/go-sqlite3"
"log"
"time"
"strconv"
)
var dbmap = initDb()
func main(){
defer dbmap.Db.Close()
router := gin.Default()
router.GET("/articles", ArticlesList)
router.POST("/articles", ArticlePost)
router.GET("/articles/:id", ArticlesDetail)
router.Run(":8000")
}
type Article struct {
Id int64 `db:"article_id"`
Created int64
Title string
Content string
}
func createArticle(title, body string) Article {
article := Article{
Created: time.Now().UnixNano(),
Title: title,
Content: body,
}
err := dbmap.Insert(&article)
checkErr(err, "Insert failed")
return article
}
func getArticle(article_id int) Article {
article := Article{}
err := dbmap.SelectOne(&article, "select * from articles where article_id=?", article_id)
checkErr(err, "SelectOne failed")
return article
}
func ArticlesList(c *gin.Context) {
var articles []Article
_, err := dbmap.Select(&articles, "select * from articles order by article_id")
checkErr(err, "Select failed")
content := gin.H{}
for k, v := range articles {
content[strconv.Itoa(k)] = v
}
c.JSON(200, content)
}
func ArticlesDetail(c *gin.Context) {
article_id := c.Params.ByName("id")
a_id, _ := strconv.Atoi(article_id)
article := getArticle(a_id)
content := gin.H{"title": article.Title, "content": article.Content}
c.JSON(200, content)
}
func ArticlePost(c *gin.Context) {
var json Article
c.Bind(&json) // This will infer what binder to use depending on the content-type header.
article := createArticle(json.Title, json.Content)
if article.Title == json.Title {
content := gin.H{
"result": "Success",
"title": article.Title,
"content": article.Content,
}
c.JSON(201, content)
} else {
c.JSON(500, gin.H{"result": "An error occured"})
}
}
func initDb() *gorp.DbMap {
db, err := sql.Open("sqlite3", "db.sqlite3")
checkErr(err, "sql.Open failed")
dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
dbmap.AddTableWithName(Article{}, "articles").SetKeys(true, "Id")
err = dbmap.CreateTablesIfNotExists()
checkErr(err, "Create tables failed")
return dbmap
}
func checkErr(err error, msg string) {
if err != nil {
log.Fatalln(msg, err)
}
}
@xluffy
Copy link

xluffy commented Oct 23, 2015

@phalt: Can you post sql for create database? Thanks

@wgriffioen
Copy link

@xluffy: That's not necessary. The database is created automatically by gorp on line 96

@mvnce
Copy link

mvnce commented Sep 12, 2016

@xluffy: If you don't use ORM. Here is the SQL statement(for sqlite3) for creating the article table.
CREATE TABLE article (
id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
title varchar(255) NOT NULL DEFAULT '',
content varchar(255) NOT NULL DEFAULT '',
created datetime NOT NULL)

Most of ORMs will lower the capitalized letters in your model.
For example:
'Id' will be 'id' in the table.
'UserId' will be 'user_id' in the table.

If you use other databases, the statement might be a little bit different.

@arthurlee
Copy link

arthurlee commented Nov 2, 2016

In the blog post, the code of line 22 is:
app.GET("/articles/:article_id", ArticleDetail)
It takes me some minutes to correct.
Thanks any way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment