Add the missing 'get' path item for RPCs to the OpenAPI output
This commit is contained in:
@@ -21,6 +21,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
+ Allows using or across related tables conditions
|
+ Allows using or across related tables conditions
|
||||||
- #1100, Customizable OpenAPI title - @AnthonyFisi
|
- #1100, Customizable OpenAPI title - @AnthonyFisi
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #2651, Add the missing `get` path item for RPCs to the OpenAPI output - @laurenceisla
|
||||||
|
|
||||||
## [10.1.2] - 2023-02-01
|
## [10.1.2] - 2023-02-01
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -73,9 +73,15 @@ toSwaggerType colType = case T.takeEnd 2 colType of
|
|||||||
"[]" -> Just SwaggerArray
|
"[]" -> Just SwaggerArray
|
||||||
_ -> Just SwaggerString
|
_ -> Just SwaggerString
|
||||||
|
|
||||||
makeSwaggerItemType :: Maybe (SwaggerType t) -> Text -> Maybe (Referenced Schema)
|
typeFromArray :: Text -> Text
|
||||||
makeSwaggerItemType itemType colType = case itemType of
|
typeFromArray = T.dropEnd 2
|
||||||
Just SwaggerArray -> Just $ Inline (mempty & type_ .~ toSwaggerType (T.dropEnd 2 colType))
|
|
||||||
|
toSwaggerTypeFromArray :: Text -> Maybe (SwaggerType t)
|
||||||
|
toSwaggerTypeFromArray arrType = toSwaggerType $ typeFromArray arrType
|
||||||
|
|
||||||
|
makePropertyItems :: Text -> Maybe (Referenced Schema)
|
||||||
|
makePropertyItems arrType = case toSwaggerType arrType of
|
||||||
|
Just SwaggerArray -> Just $ Inline (mempty & type_ .~ toSwaggerTypeFromArray arrType)
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
parseDefault :: Text -> Text -> Text
|
parseDefault :: Text -> Text -> Text
|
||||||
@@ -129,7 +135,6 @@ makeProperty tbl rels col = (colName col, Inline s)
|
|||||||
Just $ T.append (maybe "" (`T.append` "\n\n") $ colDescription col) (T.intercalate "\n" n)
|
Just $ T.append (maybe "" (`T.append` "\n\n") $ colDescription col) (T.intercalate "\n" n)
|
||||||
else
|
else
|
||||||
colDescription col
|
colDescription col
|
||||||
pType = toSwaggerType (colType col)
|
|
||||||
s =
|
s =
|
||||||
(mempty :: Schema)
|
(mempty :: Schema)
|
||||||
& default_ .~ (JSON.decode . toUtf8Lazy . parseDefault (colType col) =<< colDefault col)
|
& default_ .~ (JSON.decode . toUtf8Lazy . parseDefault (colType col) =<< colDefault col)
|
||||||
@@ -137,8 +142,8 @@ makeProperty tbl rels col = (colName col, Inline s)
|
|||||||
& enum_ .~ e
|
& enum_ .~ e
|
||||||
& format ?~ colType col
|
& format ?~ colType col
|
||||||
& maxLength .~ (fromIntegral <$> colMaxLen col)
|
& maxLength .~ (fromIntegral <$> colMaxLen col)
|
||||||
& type_ .~ pType
|
& type_ .~ toSwaggerType (colType col)
|
||||||
& items .~ (SwaggerItemsObject <$> makeSwaggerItemType pType (colType col))
|
& items .~ (SwaggerItemsObject <$> makePropertyItems (colType col))
|
||||||
|
|
||||||
makeProcSchema :: ProcDescription -> Schema
|
makeProcSchema :: ProcDescription -> Schema
|
||||||
makeProcSchema pd =
|
makeProcSchema pd =
|
||||||
@@ -153,7 +158,7 @@ makeProcProperty (ProcParam n t _ _) = (n, Inline s)
|
|||||||
where
|
where
|
||||||
s = (mempty :: Schema)
|
s = (mempty :: Schema)
|
||||||
& type_ .~ toSwaggerType t
|
& type_ .~ toSwaggerType t
|
||||||
& items .~ (SwaggerItemsObject <$> makeSwaggerItemType (toSwaggerType t) t)
|
& items .~ (SwaggerItemsObject <$> makePropertyItems t)
|
||||||
& format ?~ t
|
& format ?~ t
|
||||||
|
|
||||||
makePreferParam :: [Text] -> Param
|
makePreferParam :: [Text] -> Param
|
||||||
@@ -175,8 +180,37 @@ makePreferParam ts =
|
|||||||
"resolution" -> ["resolution=ignore-duplicates", "resolution=merge-duplicates"]
|
"resolution" -> ["resolution=ignore-duplicates", "resolution=merge-duplicates"]
|
||||||
_ -> []
|
_ -> []
|
||||||
|
|
||||||
makeProcParam :: ProcDescription -> [Referenced Param]
|
makeProcGetParam :: ProcParam -> Referenced Param
|
||||||
makeProcParam pd =
|
makeProcGetParam (ProcParam n t r v) =
|
||||||
|
Inline $ (mempty :: Param)
|
||||||
|
& name .~ n
|
||||||
|
& required ?~ r
|
||||||
|
& schema .~ ParamOther fullSchema
|
||||||
|
where
|
||||||
|
fullSchema = if v then schemaMulti else schemaNotMulti
|
||||||
|
baseSchema = (mempty :: ParamOtherSchema)
|
||||||
|
& in_ .~ ParamQuery
|
||||||
|
schemaNotMulti = baseSchema
|
||||||
|
& format ?~ t
|
||||||
|
& type_ ?~ toParamType (toSwaggerType t)
|
||||||
|
schemaMulti = baseSchema
|
||||||
|
& type_ ?~ fromMaybe SwaggerString (toSwaggerType t)
|
||||||
|
& items ?~ SwaggerItemsPrimitive (Just CollectionMulti)
|
||||||
|
((mempty :: ParamSchema x)
|
||||||
|
& type_ .~ toSwaggerTypeFromArray t
|
||||||
|
& format ?~ typeFromArray t)
|
||||||
|
toParamType paramType = case paramType of
|
||||||
|
-- Array uses {} in query params
|
||||||
|
Just SwaggerArray -> SwaggerString
|
||||||
|
-- Type must be specified in query params
|
||||||
|
Nothing -> SwaggerString
|
||||||
|
_ -> fromJust paramType
|
||||||
|
|
||||||
|
makeProcGetParams :: [ProcParam] -> [Referenced Param]
|
||||||
|
makeProcGetParams = fmap makeProcGetParam
|
||||||
|
|
||||||
|
makeProcPostParams :: ProcDescription -> [Referenced Param]
|
||||||
|
makeProcPostParams pd =
|
||||||
[ Inline $ (mempty :: Param)
|
[ Inline $ (mempty :: Param)
|
||||||
& name .~ "args"
|
& name .~ "args"
|
||||||
& required ?~ True
|
& required ?~ True
|
||||||
@@ -313,14 +347,19 @@ makeProcPathItem pd = ("/rpc/" ++ toS (pdName pd), pe)
|
|||||||
-- We strip leading newlines from description so that users can include a blank line between summary and description
|
-- We strip leading newlines from description so that users can include a blank line between summary and description
|
||||||
(pSum, pDesc) = fmap fst &&& fmap (T.dropWhile (=='\n') . snd) $
|
(pSum, pDesc) = fmap fst &&& fmap (T.dropWhile (=='\n') . snd) $
|
||||||
T.breakOn "\n" <$> pdDescription pd
|
T.breakOn "\n" <$> pdDescription pd
|
||||||
postOp = (mempty :: Operation)
|
procOp = (mempty :: Operation)
|
||||||
& summary .~ pSum
|
& summary .~ pSum
|
||||||
& description .~ mfilter (/="") pDesc
|
& description .~ mfilter (/="") pDesc
|
||||||
& parameters .~ makeProcParam pd
|
|
||||||
& tags .~ Set.fromList ["(rpc) " <> pdName pd]
|
& tags .~ Set.fromList ["(rpc) " <> pdName pd]
|
||||||
& produces ?~ makeMimeList [MTApplicationJSON, MTSingularJSON]
|
& produces ?~ makeMimeList [MTApplicationJSON, MTSingularJSON]
|
||||||
& at 200 ?~ "OK"
|
& at 200 ?~ "OK"
|
||||||
pe = (mempty :: PathItem) & post ?~ postOp
|
getOp = procOp
|
||||||
|
& parameters .~ makeProcGetParams (pdParams pd)
|
||||||
|
postOp = procOp
|
||||||
|
& parameters .~ makeProcPostParams pd
|
||||||
|
pe = (mempty :: PathItem)
|
||||||
|
& get ?~ getOp
|
||||||
|
& post ?~ postOp
|
||||||
|
|
||||||
makeRootPathItem :: (FilePath, PathItem)
|
makeRootPathItem :: (FilePath, PathItem)
|
||||||
makeRootPathItem = ("/", p)
|
makeRootPathItem = ("/", p)
|
||||||
|
|||||||
@@ -708,7 +708,153 @@ spec actualPgVersion = describe "OpenAPI" $ do
|
|||||||
|
|
||||||
describe "RPC" $ do
|
describe "RPC" $ do
|
||||||
|
|
||||||
it "includes function summary/description and body schema for arguments" $ do
|
it "includes function summary/description and query parameters for arguments in the get path item" $ do
|
||||||
|
r <- simpleBody <$> get "/"
|
||||||
|
|
||||||
|
let method s = key "paths" . key "/rpc/varied_arguments_openapi" . key s
|
||||||
|
args = r ^? method "get" . key "parameters"
|
||||||
|
summary = r ^? method "get" . key "summary"
|
||||||
|
description = r ^? method "get" . key "description"
|
||||||
|
|
||||||
|
liftIO $ do
|
||||||
|
|
||||||
|
summary `shouldBe` Just "An RPC function"
|
||||||
|
|
||||||
|
description `shouldBe` Just "Just a test for RPC function arguments"
|
||||||
|
|
||||||
|
args `shouldBe` Just
|
||||||
|
[aesonQQ|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"format": "double precision",
|
||||||
|
"in": "query",
|
||||||
|
"name": "double",
|
||||||
|
"required": true,
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "character varying",
|
||||||
|
"in": "query",
|
||||||
|
"name": "varchar",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "boolean",
|
||||||
|
"in": "query",
|
||||||
|
"name": "boolean",
|
||||||
|
"required": true,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "date",
|
||||||
|
"in": "query",
|
||||||
|
"name": "date",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "money",
|
||||||
|
"in": "query",
|
||||||
|
"name": "money",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "enum_menagerie_type",
|
||||||
|
"in": "query",
|
||||||
|
"name": "enum",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "text[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "text_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "integer[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "int_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "boolean[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "bool_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "character[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "char_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "character varying[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "varchar_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "bigint[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "bigint_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "numeric[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "numeric_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "json[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "json_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "jsonb[]",
|
||||||
|
"in": "query",
|
||||||
|
"name": "jsonb_arr",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "integer",
|
||||||
|
"in": "query",
|
||||||
|
"name": "integer",
|
||||||
|
"required": false,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "json",
|
||||||
|
"in": "query",
|
||||||
|
"name": "json",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "jsonb",
|
||||||
|
"in": "query",
|
||||||
|
"name": "jsonb",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|]
|
||||||
|
|
||||||
|
it "includes function summary/description and body schema for arguments in the post path item" $ do
|
||||||
r <- simpleBody <$> get "/"
|
r <- simpleBody <$> get "/"
|
||||||
|
|
||||||
let method s = key "paths" . key "/rpc/varied_arguments_openapi" . key s
|
let method s = key "paths" . key "/rpc/varied_arguments_openapi" . key s
|
||||||
@@ -873,6 +1019,26 @@ spec actualPgVersion = describe "OpenAPI" $ do
|
|||||||
|
|
||||||
liftIO $ params `shouldBe` Just [aesonQQ|["num", "str"]|]
|
liftIO $ params `shouldBe` Just [aesonQQ|["num", "str"]|]
|
||||||
|
|
||||||
|
it "uses a multi collection format when the function has a VARIADIC parameter" $ do
|
||||||
|
r <- simpleBody <$> get "/"
|
||||||
|
let param = r ^? key "paths" . key "/rpc/variadic_param"
|
||||||
|
. key "get" . key "parameters" . nth 0
|
||||||
|
|
||||||
|
liftIO $ param `shouldBe` Just
|
||||||
|
[aesonQQ|
|
||||||
|
{
|
||||||
|
"collectionFormat": "multi",
|
||||||
|
"in": "query",
|
||||||
|
"items": {
|
||||||
|
"format": "text",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": "v",
|
||||||
|
"required": false,
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
|]
|
||||||
|
|
||||||
describe "Security" $
|
describe "Security" $
|
||||||
it "does not include security or security definitions by default" $ do
|
it "does not include security or security definitions by default" $ do
|
||||||
r <- simpleBody <$> get "/"
|
r <- simpleBody <$> get "/"
|
||||||
|
|||||||
Reference in New Issue
Block a user