-
Notifications
You must be signed in to change notification settings - Fork 14
Example
The following is a sample Go web service that is tested with Dredd and goodman to help you understand how goodman can be used to help bootstrap your application. Specifically, it will be used to seed the web application's database before API endpoints that query the database are requested. This example will be using a sqlite database.
This example uses govendor, you must install this prior to running the example
##Important Details
All files referenced in this section will assume the current working directory of $GOPATH/src/github.com/snikch/goodman/example
.
The api.apib file
FORMAT: 1A
# My Api
## GET /message
+ Response 200 (text/html; charset=utf-8)
+ Body
Hello World!
# Group Users
## Endpoint [/users/{id}]
+ Parameters
- id: 1 - (number) - Unique identifier for a user
### Getting a single user [GET]
+ Response 200 (application/json)
+ Body
{
"Id": 1,
"Name": "Dom",
"Email": "[email protected]"
}
The api blueprint file specifies two endpoints /message
and /users/{id}
. The /message
endpoint is not very interesting but the /users/{id}
endpoint in a typical application would query a database for a user with the id given in the URL. We will use the goodman hooks to seed the database prior to Dredd making a request to this endpoint.
The go app we are testing is in a single file in main.go
// main.go
package main
import (
"database/sql"
"encoding/json"
"log"
"net/http"
_ "github.com/mattn/go-sqlite3"
)
type User struct {
Id int
Name string
Email string
}
func main() {
http.HandleFunc("/users/1", func(w http.ResponseWriter, r *http.Request) {
db, err := sql.Open("sqlite3", "./foo.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
rows, err := db.Query(`select id, name, email from users where id = ?;`, 1)
if err != nil {
panic(err)
}
var id int
var name string
var email string
for rows.Next() {
err = rows.Scan(&id, &name, &email)
if err != nil {
log.Fatal(err)
}
}
user := &User{
Id: id,
Name: name,
Email: email,
}
data, err := json.Marshal(user)
if err != nil {
panic("Marshaling failed with message " + err.Error())
}
w.Header().Add("Content-Type", "application/json")
w.Write(data)
})
http.HandleFunc("/message", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.Write([]byte("Hello World!\n"))
})
err := http.ListenAndServe(":8080", nil) // set listen port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
This go app is an http server that listens of port 8080 and has two endpoints registered: /message
, and /users/1
. As you can see from the code the users endpoint queries a sqlite database for a user with the id of 1. In order for this to succeed when Dredd is run we need to seed the database with a user before the test is run. This seeding is done in the following hookfile.
hooks/hooks.go
package main
import (
"database/sql"
"log"
"os"
_ "github.com/mattn/go-sqlite3"
"github.com/snikch/goodman/hooks"
trans "github.com/snikch/goodman/transaction"
)
var (
db sql.DB
)
func main() {
h := hooks.NewHooks()
server := hooks.NewServer(h)
db, err := sql.Open("sqlite3", "./foo.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
h.BeforeAll(func(t []*trans.Transaction) {
_, err = db.Exec(`create table users (id integer not null primary key, name text, email text);`)
if err != nil {
log.Fatal(err)
}
})
h.Before("Users > Endpoint > Getting a single user", func(t *trans.Transaction) {
_, err = db.Exec(`insert into users (id, name, email) values (1, 'Dom', '[email protected]');`)
if err != nil {
log.Fatal(err)
}
})
h.AfterAll(func(t []*trans.Transaction) {
os.Remove("./foo.db")
})
server.Serve()
defer server.Listener.Close()
}
As you can see in this file, it opens a sqlite database, creates a users table, and before the Users > Endpoint > Getting a single user
transaction, seeds a user with an id of 1 into the database. Dredd will tell goodman when the transaction is about to happen and the hook callback will be executed so that when the /users/1
endpoint is requested the necessary data exist in the database.
##Running the example
-
Install the command if you haven't already, instructions can be found here
-
Move to example directory
cd $GOPATH/src/github.com/snikch/goodman/example
- Install dredd through package.json provided
# Make sure cwd is $GOPATH/src/github.com/snikch/goodman/example
npm install
- Install vendor'ed libraries through govendor
# Make sure cwd is $GOPATH/src/github.com/snikch/goodman/example
$GOPATH/bin/govendor sync
- Run dredd with the provided Makefile
make dredd
- The Makefile (and dredd target) is provided to compile both the hooks/hooks.go and main.go files and then run dredd. This is so that the necessary steps can be executed in a single command. Please see the Makefile for more details.