Tuesday, 17 June 2014

A Dummy REST API with Go Lang

Sometimes I just want to try out a few ideas in a HTML/JavaScript client without having to scaffold a server to provide a bunch of RESTful APIs so I've built myself a dummy REST API to do just that.

Here's how I did it!

My requirements were:
  • Serve up the contents of a file based on a route for example \Customers would serve a file in the \Customers directory
  • Allow Cross-origin resource sharing and/or JSONP 
  • Allow me to change the JSON being served without having to restart anything

I decided to write the server in Go Lang since it's fun to scaffold up http web services with and the resultant utility will be cross platform so I can tinker away on my Mac with few issues. I've used Martini framework to get up and running quickly.

So the file directory will contain the files that I want to serve up as per:




The code to scan the file directory for the files is straightforward:

func (routes *RoutesImpl) Load() {
OrgPath := "./"
Recurse := true
walkFn := func(path string, info os.FileInfo, err error) error {
stat, err := os.Stat(path)
if err != nil {
return err
}
if stat.IsDir() && path != OrgPath && !Recurse {
return filepath.SkipDir
}
if err != nil {
return err
}
if stat.IsDir() {
routes.routelist = append(routes.routelist, Route{path})
}
return nil
}
filepath.Walk(OrgPath, walkFn)
}
view raw gistfile1.txt hosted with ❤ by GitHub
The code to serve up the file based on the matching route:

func ParseRoute(service *ServiceImpl) martini.Handler {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-type", "application/json")
for _, b := range service.routes {
path := strings.TrimPrefix(r.URL.Path, "/")
if b.path == path {
if r.Method == "GET" {
fmt.Println(r.URL.RawQuery)
m, _ := url.ParseQuery(r.URL.RawQuery)
// need to wrap the file in a function if jsonp
content, _ := ioutil.ReadFile(b.path + "/GET")
// check to see if this is a jsonp call
if value, ok := m["callback"]; ok {
s := fmt.Sprintf("%s(%s)", value[0], string(content))
io.WriteString(w, s)
} else {
io.WriteString(w, string(content))
}
}
}
}
fmt.Println(r.URL.Path)
r.URL.Path = ""
}
}
view raw gistfile1.go hosted with ❤ by GitHub
So with the GET file populated with some appropriate JSON:



So now when we run the servicestub application:



And if we choose a specific item:




Now to write some JavaScript!

Code here:

A cross platform tool for mocking API servicesRead More

Latest commit to the master branch on 6-17-2014
Download as zip