Creating a Basic Web App

Now that we are done going over the basics of HTTP, let's create a simple butuseful web application in Go.

Pulling from our fileserver program that we implemented last chapter, we willimplement a Markdown generator using the github.com/russross/blackfridaypackage.

HTML Form

For starters, we will need a basic HTML form for the markdown input:

  1. <html>
  2. <head>
  3. <link href="/css/bootstrap.min.css" rel="stylesheet">
  4. </head>
  5. <body>
  6. <div class="container">
  7. <div class="page-title">
  8. <h1>Markdown Generator</h1>
  9. <p class="lead">Generate your markdown with Go</p>
  10. <hr />
  11. </div>
  12. <form action="/markdown" method="POST">
  13. <div class="form-group">
  14. <textarea class="form-control" name="body" cols="30" rows="10"></textarea>
  15. </div>
  16. <div class="form-group">
  17. <input type="submit" class="btn btn-primary pull-right" />
  18. </div>
  19. </form>
  20. </div>
  21. <script src="/js/bootstrap.min.js"></script>
  22. </body>
  23. </html>

Put this HTML into a file named index.html in the "public" folder of our applicationand the bootstrap.min.css from http://getbootstrap.com/ in the "public/css" folder.Notice that the form makes an HTTP POST to the "/markdown" endpoint of ourapplication. We don't actually handle that route right now, so let's add it.

The "/markdown" route

The program to handle the '/markdown' route and serve the public index.htmlfile looks like this:

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/russross/blackfriday"
  5. )
  6. func main() {
  7. http.HandleFunc("/markdown", GenerateMarkdown)
  8. http.Handle("/", http.FileServer(http.Dir("public")))
  9. http.ListenAndServe(":8080", nil)
  10. }
  11. func GenerateMarkdown(rw http.ResponseWriter, r *http.Request) {
  12. markdown := blackfriday.MarkdownCommon([]byte(r.FormValue("body")))
  13. rw.Write(markdown)
  14. }

Let's break it down into smaller pieces to get a better idea of what is goingon.

  1. http.HandleFunc("/markdown", GenerateMarkdown)
  2. http.Handle("/", http.FileServer(http.Dir("public")))

We are using the http.HandleFunc and http.Handle methods to define somesimple routing for our application. It is important to note that callinghttp.Handle on the "/" pattern will act as a catch-all route, so we definethat route last. http.FileServer returns an http.Handler so we usehttp.Handle to map a pattern string to a handler. The alternative method,http.HandleFunc, uses an http.HandlerFunc instead of an http.Handler.This may be more convenient, to think of handling routes via a functioninstead of an object.

  1. func GenerateMarkdown(rw http.ResponseWriter, r *http.Request) {
  2. markdown := blackfriday.MarkdownCommon([]byte(r.FormValue("body")))
  3. rw.Write(markdown)
  4. }

Our GenerateMarkdown function implements the standard http.HandlerFuncinterface and renders HTML from a form field containingmarkdown-formatted text. In this case, the content is retrievedwith r.FormValue("body"). It is very common to get input from thehttp.Request object that the http.HandlerFunc receives as an argument.Some other examples of input are the r.Header, r.Body, and r.URL members.

We finalize the request by writing it out to our http.ResponseWriter. Noticethat we didn't explicitly send a response code. If we write out to the responsewithout a code, the net/http package will assume that the response is a 200
OK
. This means that if something did happen to go wrong, we should set theresponse code via the rw.WriteHeader() method.

  1. http.ListenAndServe(":8080", nil)

The last bit of this program starts the server, we pass nil as our handler,which assumes that the HTTP requests will be handled by the net/http packagesdefault http.ServeMux, which is configured using http.Handle andhttp.HandleFunc, respectively.

And that is all you need to be able to generate markdown as a service in Go. Itis a surprisingly small amount of code for the amount of heavy lifting it does.In the next chapter we will learn how to deploy this application to the webusing Heroku.

原文: https://codegangsta.gitbooks.io/building-web-apps-with-go/content/creating_a_basic_web_app/index.html