From 4dbf13c6d865d70a2c490311af855dcb7a04d958 Mon Sep 17 00:00:00 2001 From: RussellLuo Date: Mon, 18 Jul 2022 11:42:25 +0800 Subject: [PATCH] oas2: Add support for content negotiation Now we can request an API document in JSON format. For example (via HTTPie): ``` $ http GET :8080/api Accept:application/json $ http GET :8080/api?accept=json ``` --- go.mod | 2 +- go.sum | 7 +++++-- pkg/oas2/oas2.go | 25 +++++++++++++++++++++++-- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 382bdf7..2f2d99b 100644 --- a/go.mod +++ b/go.mod @@ -13,5 +13,5 @@ require ( golang.org/x/tools v0.1.10 google.golang.org/grpc v1.36.0 google.golang.org/protobuf v1.27.1 - gopkg.in/yaml.v2 v2.2.8 + sigs.k8s.io/yaml v1.3.0 ) diff --git a/go.sum b/go.sum index 75eea70..0325a03 100644 --- a/go.sum +++ b/go.sum @@ -47,6 +47,7 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -424,11 +425,13 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/pkg/oas2/oas2.go b/pkg/oas2/oas2.go index aa12bc8..94c0175 100644 --- a/pkg/oas2/oas2.go +++ b/pkg/oas2/oas2.go @@ -8,6 +8,8 @@ import ( "strconv" "strings" "text/template" + + "sigs.k8s.io/yaml" ) var ( @@ -209,7 +211,26 @@ type APIDocFunc func(schema Schema) string func Handler(apiDocFn APIDocFunc, schema Schema) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - fmt.Fprintln(w, apiDocFn(schema)) + yamlContent := []byte(apiDocFn(schema)) + + if r.Header.Get("Accept") == "application/json" || r.URL.Query().Get("accept") == "json" { + // Content negotiation methods: + // + // Accept: application/json + // ?accept=json + + jsonContent, err := yaml.YAMLToJSON(yamlContent) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json; charset=utf-8") + _, _ = w.Write(jsonContent) + return + } + + w.Header().Set("Content-Type", "text/yaml; charset=utf-8") + _, _ = w.Write(yamlContent) } }