break: db-root-spec default app/openapi+json media
BREAKING CHANGE Can be done later with custom media types
This commit is contained in:
committed by
Steve Chavez
parent
14d030b96c
commit
4a90e9fbd9
@@ -92,6 +92,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
+ Can be replaced with custom media types
|
||||
- #1462, #1548, Removed `application/octet-stream`, `text/plain`, `text/xml` [builtin support for scalar results](https://postgrest.org/en/v11.1/references/api/resource_representation.html#scalar-function-response-format) - @steve-chavez
|
||||
+ Can be replaced with custom media types
|
||||
- #1462, #1548, Removed default `application/openapi+json` media type for [db-root-spec](https://postgrest.org/en/v11.1/references/configuration.html#db-root-spec) - @steve-chavez
|
||||
|
||||
## [11.1.0] - 2023-06-07
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ module PostgREST.ApiRequest
|
||||
, Action(..)
|
||||
, Target(..)
|
||||
, Payload(..)
|
||||
, PathInfo(..)
|
||||
, userApiRequest
|
||||
) where
|
||||
|
||||
@@ -127,7 +126,6 @@ data ApiRequest = ApiRequest {
|
||||
, iHeaders :: [(ByteString, ByteString)] -- ^ HTTP request headers
|
||||
, iCookies :: [(ByteString, ByteString)] -- ^ Request Cookies
|
||||
, iPath :: ByteString -- ^ Raw request path
|
||||
, iPathInfo :: PathInfo -- ^ Cached info about the path
|
||||
, iMethod :: ByteString -- ^ Raw request method
|
||||
, iSchema :: Schema -- ^ The request schema. Can vary depending on profile headers.
|
||||
, iNegotiatedByProfile :: Bool -- ^ If schema was was chosen according to the profile spec https://www.w3.org/TR/dx-prof-conneg/
|
||||
@@ -158,7 +156,6 @@ userApiRequest conf req reqBody = do
|
||||
, iHeaders = iHdrs
|
||||
, iCookies = iCkies
|
||||
, iPath = rawPathInfo req
|
||||
, iPathInfo = pInfo
|
||||
, iMethod = method
|
||||
, iSchema = schema
|
||||
, iNegotiatedByProfile = negotiatedByProfile
|
||||
|
||||
+10
-14
@@ -41,7 +41,6 @@ import PostgREST.ApiRequest (Action (..),
|
||||
ApiRequest (..),
|
||||
InvokeMethod (..),
|
||||
Mutation (..),
|
||||
PathInfo (..),
|
||||
Payload (..))
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
import PostgREST.Error (Error (..))
|
||||
@@ -123,7 +122,7 @@ data InspectPlan = InspectPlan {
|
||||
wrappedReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> Either Error WrappedReadPlan
|
||||
wrappedReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} = do
|
||||
rPlan <- readPlan identifier conf sCache apiRequest
|
||||
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType
|
||||
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iAcceptMediaType
|
||||
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
|
||||
return $ WrappedReadPlan rPlan SQL.Read (mediaToAggregate mediaType apiRequest) mediaType
|
||||
|
||||
@@ -131,7 +130,7 @@ mutateReadPlan :: Mutation -> ApiRequest -> QualifiedIdentifier -> AppConfig ->
|
||||
mutateReadPlan mutation apiRequest@ApiRequest{iPreferences=Preferences{..},..} identifier conf sCache = do
|
||||
rPlan <- readPlan identifier conf sCache apiRequest
|
||||
mPlan <- mutatePlan mutation identifier apiRequest sCache rPlan
|
||||
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType
|
||||
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iAcceptMediaType
|
||||
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
|
||||
return $ MutateReadPlan rPlan mPlan SQL.Write (mediaToAggregate mediaType apiRequest) mediaType
|
||||
|
||||
@@ -157,7 +156,7 @@ callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferenc
|
||||
(InvPost, Routine.Immutable) -> SQL.Read
|
||||
(InvPost, Routine.Volatile) -> SQL.Write
|
||||
cPlan = callPlan proc apiRequest paramKeys args rPlan
|
||||
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iPathInfo iAcceptMediaType
|
||||
mediaType <- mapLeft ApiRequestError $ negotiateContent conf iAction iAcceptMediaType
|
||||
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
|
||||
return $ CallReadPlan rPlan cPlan txMode proc (mediaToAggregate mediaType apiRequest) mediaType
|
||||
where
|
||||
@@ -165,7 +164,7 @@ callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferenc
|
||||
|
||||
inspectPlan :: AppConfig -> ApiRequest -> Either Error InspectPlan
|
||||
inspectPlan conf apiRequest = do
|
||||
mediaType <- mapLeft ApiRequestError $ negotiateContent conf (iAction apiRequest) (iPathInfo apiRequest) (iAcceptMediaType apiRequest)
|
||||
mediaType <- mapLeft ApiRequestError $ negotiateContent conf (iAction apiRequest) (iAcceptMediaType apiRequest)
|
||||
return $ InspectPlan mediaType SQL.Read
|
||||
|
||||
{-|
|
||||
@@ -851,29 +850,26 @@ mediaToAggregate mt apiReq@ApiRequest{iAction=act, iPreferences=Preferences{pref
|
||||
_ -> False
|
||||
|
||||
-- | Do content negotiation. i.e. choose a media type based on the intersection of accepted/produced media types.
|
||||
negotiateContent :: AppConfig -> Action -> PathInfo -> [MediaType] -> Either ApiRequestError MediaType
|
||||
negotiateContent conf action path accepts =
|
||||
negotiateContent :: AppConfig -> Action -> [MediaType] -> Either ApiRequestError MediaType
|
||||
negotiateContent conf action accepts =
|
||||
case firstAcceptedPick of
|
||||
Just MTAny -> Right MTApplicationJSON -- by default(for */*) we respond with json
|
||||
Just mt -> Right mt
|
||||
Nothing -> Left . MediaTypeError $ map MediaType.toMime accepts
|
||||
where
|
||||
-- if there are multiple accepted media types, pick the first
|
||||
firstAcceptedPick = listToMaybe $ L.intersect accepts $ producedMediaTypes conf action path
|
||||
firstAcceptedPick = listToMaybe $ L.intersect accepts $ producedMediaTypes conf action
|
||||
|
||||
producedMediaTypes :: AppConfig -> Action -> PathInfo -> [MediaType]
|
||||
producedMediaTypes conf action path =
|
||||
producedMediaTypes :: AppConfig -> Action -> [MediaType]
|
||||
producedMediaTypes conf action =
|
||||
case action of
|
||||
ActionRead _ -> defaultMediaTypes
|
||||
ActionInvoke _ -> invokeMediaTypes
|
||||
ActionInvoke _ -> defaultMediaTypes
|
||||
ActionInfo -> defaultMediaTypes
|
||||
ActionMutate _ -> defaultMediaTypes
|
||||
ActionInspect _ -> inspectMediaTypes
|
||||
where
|
||||
inspectMediaTypes = [MTOpenAPI, MTApplicationJSON, MTArrayJSONStrip, MTAny]
|
||||
invokeMediaTypes =
|
||||
defaultMediaTypes
|
||||
++ [MTOpenAPI | pathIsRootSpec path]
|
||||
defaultMediaTypes =
|
||||
[MTApplicationJSON, MTArrayJSONStrip, MTSingularJSON True, MTSingularJSON False, MTGeoJSON, MTTextCSV] ++
|
||||
[MTPlan MTApplicationJSON PlanText mempty | configDbPlanEnabled conf] ++ [MTAny]
|
||||
|
||||
@@ -3,7 +3,7 @@ module Feature.OpenApi.RootSpec where
|
||||
import Network.HTTP.Types
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Test.Hspec
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
@@ -12,7 +12,8 @@ import Protolude hiding (get)
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
describe "root spec function" $ do
|
||||
it "accepts application/openapi+json" $
|
||||
it "accepts application/openapi+json" $ do
|
||||
pendingWith "TBD"
|
||||
request methodGet "/"
|
||||
[("Accept","application/openapi+json")] "" `shouldRespondWith`
|
||||
[json|{
|
||||
|
||||
Reference in New Issue
Block a user