Per-route content negotiation, and OpenAPI only for root (#693)

* WIP: remove non-openapi root spec

* Refactor ContentType

Different endpoints will favor one type over another

* Permit different Accept headers per endpoint

* Lint

* Add charset to Content-Type only when used as a header

Keep it out of error messages

* Accept: */* is last resort, not first

* Changelog

* makeMimeList consistently

* Remove schema description from OPTIONS response
This commit is contained in:
Joe Nelson
2016-08-19 16:07:22 -07:00
committed by GitHub
parent 35c5b190b4
commit 1d5a0e4316
9 changed files with 126 additions and 493 deletions
+3 -18
View File
@@ -8,20 +8,17 @@ import qualified Data.HashMap.Strict as M
import Data.String.Conversions (cs)
import qualified Hasql.Transaction as H
import Network.HTTP.Types.Header (hAccept)
import Network.HTTP.Types.Status (status400, status415)
import Network.Wai (Application, Request (..),
Response, requestHeaders)
import Network.HTTP.Types.Status (status400)
import Network.Wai (Application, Response)
import Network.Wai.Middleware.Cors (cors)
import Network.Wai.Middleware.Gzip (def, gzip)
import Network.Wai.Middleware.Static (only, staticPolicy)
import PostgREST.ApiRequest (ApiRequest(..), ContentType(..), pickContentType)
import PostgREST.ApiRequest (ApiRequest(..))
import PostgREST.Auth (claimsToSQL)
import PostgREST.Config (AppConfig (..), corsPolicy)
import PostgREST.Error (errResponse)
import Data.Text
import Data.List (lookup)
import Protolude hiding (concat, null)
@@ -39,20 +36,8 @@ runWithClaims conf eClaims app req =
anon = String . cs $ configAnonRole conf
clientErr = return . errResponse status400
unsupportedAccept :: Application -> Application
unsupportedAccept app req respond =
case (isTargetRoot, accept) of
(_, Left _) -> unsupportedAcceptRespond
(False, Right OpenAPI) -> unsupportedAcceptRespond
(_, Right _) -> app req respond
where accept = pickContentType $ lookup hAccept $ requestHeaders req
path = pathInfo req
isTargetRoot = fromMaybe True $ (== "") <$> listToMaybe path
unsupportedAcceptRespond = respond $ errResponse status415 "Unsupported Accept header, try: application/json"
defaultMiddle :: Application -> Application
defaultMiddle =
gzip def
. cors corsPolicy
. staticPolicy (only [("favicon.ico", "static/favicon.ico")])
. unsupportedAccept