Add the missing 'get' path item for RPCs to the OpenAPI output

This commit is contained in:
Laurence Isla
2023-02-09 12:04:41 -05:00
committed by GitHub
parent ecada119f8
commit c893ac15dc
3 changed files with 222 additions and 13 deletions
+4
View File
@@ -21,6 +21,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
+ Allows using or across related tables conditions
- #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
### Fixed
+51 -12
View File
@@ -73,9 +73,15 @@ toSwaggerType colType = case T.takeEnd 2 colType of
"[]" -> Just SwaggerArray
_ -> Just SwaggerString
makeSwaggerItemType :: Maybe (SwaggerType t) -> Text -> Maybe (Referenced Schema)
makeSwaggerItemType itemType colType = case itemType of
Just SwaggerArray -> Just $ Inline (mempty & type_ .~ toSwaggerType (T.dropEnd 2 colType))
typeFromArray :: Text -> Text
typeFromArray = T.dropEnd 2
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
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)
else
colDescription col
pType = toSwaggerType (colType col)
s =
(mempty :: Schema)
& default_ .~ (JSON.decode . toUtf8Lazy . parseDefault (colType col) =<< colDefault col)
@@ -137,8 +142,8 @@ makeProperty tbl rels col = (colName col, Inline s)
& enum_ .~ e
& format ?~ colType col
& maxLength .~ (fromIntegral <$> colMaxLen col)
& type_ .~ pType
& items .~ (SwaggerItemsObject <$> makeSwaggerItemType pType (colType col))
& type_ .~ toSwaggerType (colType col)
& items .~ (SwaggerItemsObject <$> makePropertyItems (colType col))
makeProcSchema :: ProcDescription -> Schema
makeProcSchema pd =
@@ -153,7 +158,7 @@ makeProcProperty (ProcParam n t _ _) = (n, Inline s)
where
s = (mempty :: Schema)
& type_ .~ toSwaggerType t
& items .~ (SwaggerItemsObject <$> makeSwaggerItemType (toSwaggerType t) t)
& items .~ (SwaggerItemsObject <$> makePropertyItems t)
& format ?~ t
makePreferParam :: [Text] -> Param
@@ -175,8 +180,37 @@ makePreferParam ts =
"resolution" -> ["resolution=ignore-duplicates", "resolution=merge-duplicates"]
_ -> []
makeProcParam :: ProcDescription -> [Referenced Param]
makeProcParam pd =
makeProcGetParam :: ProcParam -> Referenced Param
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)
& name .~ "args"
& 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
(pSum, pDesc) = fmap fst &&& fmap (T.dropWhile (=='\n') . snd) $
T.breakOn "\n" <$> pdDescription pd
postOp = (mempty :: Operation)
procOp = (mempty :: Operation)
& summary .~ pSum
& description .~ mfilter (/="") pDesc
& parameters .~ makeProcParam pd
& tags .~ Set.fromList ["(rpc) " <> pdName pd]
& produces ?~ makeMimeList [MTApplicationJSON, MTSingularJSON]
& 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 = ("/", p)
+167 -1
View File
@@ -708,7 +708,153 @@ spec actualPgVersion = describe "OpenAPI" $ 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 "/"
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"]|]
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" $
it "does not include security or security definitions by default" $ do
r <- simpleBody <$> get "/"