Golang is awesome for developing web apps. And people have created a bunch of awesome Web-Frameworks, Web helper libraries. If we consider the entire ecosystem of web apps in Golang everything except API documentation seems to be in place. So we have created the first API doc generator for Golang based web apps and calling it Yet another.
Most of the web services expose their APIs to the mobile or third party developers. Documenting them is somewhat pain in the ass. We are trying to reduce the pain, at least for in house projects where you don't have to expose your documentation to the world. YAAG generates simple bootstrap based API documentation without writing a single line of comments.
YAAG is a middleware. You have to add YAAG handler in your routes and you are done. Just go on calling your APIs using POSTMAN, Curl or from any client, and YAAG will keep on updating the API Doc html. (Note: We are also generating a json file containing data af all API calls)
- Import github.com/betacraft/yaag/yaag
- Import github.com/betacraft/yaag/middleware
- Initialize yaag
yaag.Init(&yaag.Config{On: true, DocTitle: "Core", DocPath: "apidoc.html"})
- Use it in your handlers as
http.HandleFunc("/", middleware.HandleFunc(handler))
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
func main() {
yaag.Init(&yaag.Config{On: true, DocTitle: "Core", DocPath: "apidoc.html", BaseUrls : map[string]string{"Production":"","Staging":""} })
http.HandleFunc("/", middleware.HandleFunc(handler))
http.ListenAndServe(":8080", nil)
}
- Import github.com/betacraft/yaag/yaag
- Import github.com/betacraft/yaag/middleware
- Initialize yaag
yaag.Init(&yaag.Config{On: true, DocTitle: "Gorilla Mux", DocPath: "apidoc.html"})
- Use it in your handlers as
r.HandleFunc("/", middleware.HandleFunc(handler))
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, time.Now().String())
}
func main() {
yaag.Init(&yaag.Config{On: true, DocTitle: "Gorilla Mux", DocPath: "apidoc.html"})
r := mux.NewRouter()
r.HandleFunc("/", middleware.HandleFunc(handler))
http.ListenAndServe(":8080", r)
}
- Import github.com/betacraft/yaag/yaag
- Import github.com/betacraft/yaag/martiniyaag
- Initialize yaag
yaag.Init(&yaag.Config{On: true, DocTitle: "Martini", DocPath: "apidoc.html"})
- Add Yaag middleware like
m.Use(martiniyaag.Document)
func main() {
yaag.Init(&yaag.Config{On: true, DocTitle: "Martini", DocPath: "apidoc.html"})
m := martini.Classic()
m.Use(martiniyaag.Document)
m.Get("/", func() string {
return "Hello world!"
})
m.Run()
}
- Add yaag.record = true in conf/app.conf (before starting to record the api calls)
- import github.com/betacraft/yaag/filters in app/init.go
- add 'filters.FilterForApiDoc' in revel.Filters
- Start recording Api calls
func init() {
// Filters is the default set of global filters.
revel.Filters = []revel.Filter{
filters.FilterForApiDoc, // This enables yaag to record apicalls
revel.PanicFilter, // Recover from panics and display an error page instead.
revel.RouterFilter, // Use the routing table to select the right Action
revel.FilterConfiguringFilter, // A hook for adding or removing per-Action filters.
revel.ParamsFilter, // Parse parameters into Controller.Params.
revel.SessionFilter, // Restore and write the session cookie.
revel.FlashFilter, // Restore and write the flash cookie.
revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie.
revel.I18nFilter, // Resolve the requested language
HeaderFilter, // Add some security based headers
revel.InterceptorFilter, // Run interceptors around the action.
revel.CompressFilter, // Compress the result.
revel.ActionInvoker, // Invoke the action.
}
revel.OnAppStart(func() {
yaag.Init(&yaag.Config{ // <- IMPORTANT, init the middleware.
On: true,
DocTitle: "Revel",
DocPath: "examples/revel/apidoc.html",
BaseUrls: map[string]string{"Production": "", "Staging": ""},
})
})
}
- Import github.com/betacraft/yaag/yaag
- Import github.com/betacraft/yaag/gin
- Initialize yaag
yaag.Init(&yaag.Config(On: true, DocTile: "Gin", DocPath: "apidpc.html"))
- Add yaag middleware like
r.User(yaag_gin.Document())
import (
"net/http"
yaag_gin "github.com/betacraft/yaag/gin/v1"
"github.com/betacraft/yaag/yaag"
"gopkg.in/gin-gonic/gin.v1"
)
func main() {
r := gin.Default()
yaag.Init(&yaag.Config{On: true, DocTitle: "Gin", DocPath: "apidoc.html", BaseUrls: map[string]string{"Production": "", "Staging": ""}})
r.Use(yaag_gin.Document())
// use other middlewares ...
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello World!")
})
r.Run(":8080")
}
import (
"net/http"
yaag_gin "github.com/betacraft/yaag/gin"
"github.com/betacraft/yaag/yaag"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
yaag.Init(&yaag.Config{On: true, DocTitle: "Gin", DocPath: "apidoc.html", BaseUrls: map[string]string{"Production": "", "Staging": ""}})
r.Use(yaag_gin.Document())
// use other middlewares ...
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello World!")
})
r.Run(":8080")
}
- Import
github.com/betacraft/yaag/yaag
- Import
github.com/betacraft/yaag/irisyaag
- Initialize yaag
yaag.Init(&yaag.Config(On: true, DocTile: "Iris", DocPath: "apidoc.html"))
- Register yaag middleware like
app.Use(irisyaag.New())
irisyaag
records the response body and provides all the necessary information to the apidoc.
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/betacraft/yaag/irisyaag"
"github.com/betacraft/yaag/yaag"
)
type myXML struct {
Result string `xml:"result"`
}
func main() {
app := iris.New()
yaag.Init(&yaag.Config{ // <- IMPORTANT, init the middleware.
On: true,
DocTitle: "Iris",
DocPath: "apidoc.html",
BaseUrls: map[string]string{"Production": "", "Staging": ""},
})
app.Use(irisyaag.New()) // <- IMPORTANT, register the middleware.
app.Get("/json", func(ctx context.Context) {
ctx.JSON(context.Map{"result": "Hello World!"})
})
app.Get("/plain", func(ctx context.Context) {
ctx.Text("Hello World!")
})
app.Get("/xml", func(ctx context.Context) {
ctx.XML(myXML{Result: "Hello World!"})
})
app.Get("/complex", func(ctx context.Context) {
value := ctx.URLParam("key")
ctx.JSON(iris.Map{"value": value})
})
// Run our HTTP Server.
//
// Note that on each incoming request the yaag will generate and update the "apidoc.html".
// Recommentation:
// Write tests that calls those handlers, save the generated "apidoc.html".
// Turn off the yaag middleware when in production.
//
// Example usage:
// Visit all paths and open the generated "apidoc.html" file to see the API's automated docs.
app.Run(iris.Addr(":8080"))
}
- Import github.com/betacraft/yaag/yaag
- Import github.com/betacraft/yaag/httprouteryaag
- Initialize yaag
yaag.Init(&yaag.Config{On: true, DocTitle: "Httprouter", DocPath: "apidoc.html"})
- Use it in your handlers as
router.Handle("GET", "/", httprouteryaag.HandleFunc(handler))
func handler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
func main() {
yaag.Init(&yaag.Config{On: true, DocTitle: "Httprouter", DocPath: "apidoc.html", BaseUrls : map[string]string{"Production":"","Staging":""} })
router := httprouter.New()
router.Handle("GET", "/", httprouteryaag.HandleFunc(handler))
http.ListenAndServe(":8080", router)
}
- Aniket Awati (aniket@betacraft.co)
- Akshay Deo (akshay@betacraft.co)
- Brian Newsom (Brian.Newsom@Colorado.edu)
This project is initiated by Betacraft during GopherGala 2015.