Add GET handler for diagram generation

This commit is contained in:
Tom Wright 2020-04-15 17:44:17 +01:00
parent b8f5abc401
commit 06b5694125
2 changed files with 67 additions and 15 deletions

View File

@ -11,7 +11,7 @@ Start the HTTP server:
go run cmd/app/main.go --mermaid=./mermaidcli/node_modules/.bin/mmdc --in=./in --out=./out
```
Send CURL request to generate a diagram:
Send CURL request to generate a diagram via `POST`:
```
curl --location --request POST 'http://localhost:80/generate' \
--header 'Content-Type: text/plain' \
@ -24,5 +24,10 @@ curl --location --request POST 'http://localhost:80/generate' \
'
```
Or send CURL request to generate a diagram via `GET`... send in url encoded data under the `data` query param:
```
curl --location --request GET 'http://localhost:80/generate?data=graph%20LR%0A%0A%20%20%20%20A--%3EB%0A%20%20%20%20B--%3EC%0A%20%20%20%20C--%3ED%0A%20%20%20%20C--%3EF%0A'
```
Inline-style:
![Example request in Postman](example.png "Example request in Postman")

View File

@ -5,6 +5,8 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
func writeJSON(rw http.ResponseWriter, value interface{}, status int) {
@ -33,31 +35,76 @@ func writeErr(rw http.ResponseWriter, err error, status int) {
}, status)
}
func GenerateHTTPHandler(generator Generator) func(rw http.ResponseWriter, r *http.Request) {
return func(rw http.ResponseWriter, r *http.Request) {
// URLParam is the URL parameter getDiagramFromGET uses to look for data.
const URLParam = "data"
func getDiagramFromGET(rw http.ResponseWriter, r *http.Request) *Diagram {
if r.Method != http.MethodGet {
writeErr(rw, fmt.Errorf("expected HTTP method GET"), http.StatusBadRequest)
return nil
}
queryVal := strings.TrimSpace(r.URL.Query().Get(URLParam))
if queryVal == "" {
writeErr(rw, fmt.Errorf("missing data"), http.StatusBadRequest)
return nil
}
data, err := url.QueryUnescape(queryVal)
if err != nil {
writeErr(rw, fmt.Errorf("could not read query param: %s", err), http.StatusBadRequest)
return nil
}
// Create a diagram from the description
d := NewDiagram([]byte(data))
return d
}
func getDiagramFromPOST(rw http.ResponseWriter, r *http.Request) *Diagram {
if r.Method != http.MethodPost {
writeErr(rw, fmt.Errorf("expected HTTP method POST"), http.StatusBadRequest)
return
return nil
}
// Get description from request body
bytes, err := ioutil.ReadAll(r.Body)
if err != nil {
writeErr(rw, fmt.Errorf("could not read body: %s", err), http.StatusInternalServerError)
return
return nil
}
// Create a diagram from the description
d := NewDiagram(bytes)
return d
}
// GenerateHTTPHandler returns a HTTP handler used to generate a diagram.
func GenerateHTTPHandler(generator Generator) func(rw http.ResponseWriter, r *http.Request) {
return func(rw http.ResponseWriter, r *http.Request) {
var diagram *Diagram
switch r.Method {
case http.MethodGet:
diagram = getDiagramFromGET(rw, r)
case http.MethodPost:
diagram = getDiagramFromPOST(rw, r)
default:
writeErr(rw, fmt.Errorf("unexpected HTTP method %s", r.Method), http.StatusBadRequest)
return
}
if diagram == nil {
writeErr(rw, fmt.Errorf("could not create diagram"), http.StatusInternalServerError)
return
}
// Generate the diagram
if err := generator.Generate(d); err != nil {
if err := generator.Generate(diagram); err != nil {
writeErr(rw, fmt.Errorf("could not generate diagram: %s", err), http.StatusInternalServerError)
return
}
// Output the diagram as an SVG.
// We assume generate always generates an SVG at this point in time.
diagramBytes, err := ioutil.ReadFile(d.Output)
diagramBytes, err := ioutil.ReadFile(diagram.Output)
if err != nil {
writeErr(rw, fmt.Errorf("could not read diagram bytes: %s", err), http.StatusInternalServerError)
return