Creating a Basic Web App
Now that we are done going over the basics of HTTP, let's create a simple but useful web application in Go.
Pulling from our fileserver program that we implemented last chapter, we will implement a Markdown generator using the github.com/russross/blackfriday
package.
HTML Form
For starters, we will need a basic HTML form for the markdown input:
<html>
<head>
<link href="/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="page-title">
<h1>Markdown Generator</h1>
<p class="lead">Generate your markdown with Go</p>
<hr />
</div>
<form action="/markdown" method="POST">
<div class="form-group">
<textarea class="form-control" name="body" cols="30" rows="10"></textarea>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary pull-right" />
</div>
</form>
</div>
<script src="/js/bootstrap.min.js"></script>
</body>
</html>
Put this HTML into a file named index.html
in the "public" folder of our application and 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 our application. 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.html
file looks like this:
package main
import (
"net/http"
"github.com/russross/blackfriday"
)
func main() {
http.HandleFunc("/markdown", GenerateMarkdown)
http.Handle("/", http.FileServer(http.Dir("public")))
http.ListenAndServe(":8080", nil)
}
func GenerateMarkdown(rw http.ResponseWriter, r *http.Request) {
markdown := blackfriday.MarkdownCommon([]byte(r.FormValue("body")))
rw.Write(markdown)
}
Let's break it down into smaller pieces to get a better idea of what is going on.
http.HandleFunc("/markdown", GenerateMarkdown)
http.Handle("/", http.FileServer(http.Dir("public")))
We are using the http.HandleFunc
and http.Handle
methods to define some simple routing for our application. It is important to note that calling http.Handle
on the "/" pattern will act as a catch-all route, so we define that route last. http.FileServer
returns an http.Handler
so we use http.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 function instead of an object.
func GenerateMarkdown(rw http.ResponseWriter, r *http.Request) {
markdown := blackfriday.MarkdownCommon([]byte(r.FormValue("body")))
rw.Write(markdown)
}
Our GenerateMarkdown function implements the standard http.HandlerFunc
interface and renders HTML from a form field containing markdown-formatted text. In this case, the content is retrieved with r.FormValue("body")
. It is very common to get input from the http.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
. Notice that we didn't explicitly send a response code. If we write out to the response without 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 the response code via the rw.WriteHeader()
method.
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
packages default http.ServeMux
, which is configured using http.Handle
and http.HandleFunc
, respectively.
And that is all you need to be able to generate markdown as a service in Go. It is 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 web using Heroku.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论