mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-17 04:24:35 +03:00
80 lines
3.3 KiB
Haskell
80 lines
3.3 KiB
Haskell
|
-- | This module exports an OpenAPI specification for the GraphQL Engine
|
||
|
-- metadata API.
|
||
|
--
|
||
|
-- The OpenAPI specification for metadata is experimental and incomplete. Please
|
||
|
-- do not incorporate it into essential workflows at this time.
|
||
|
module Hasura.Server.MetadataOpenAPI (metadataOpenAPI) where
|
||
|
|
||
|
import Autodocodec (HasCodec)
|
||
|
import Autodocodec.OpenAPI (declareNamedSchemaViaCodec)
|
||
|
import Control.Lens ((.~), (^.))
|
||
|
import Data.Data (Proxy)
|
||
|
import Data.HashMap.Strict.InsOrd qualified as HM
|
||
|
import Data.OpenApi
|
||
|
( HasComponents (components),
|
||
|
HasName (name),
|
||
|
HasSchema (schema),
|
||
|
HasSchemas (schemas),
|
||
|
OpenApi,
|
||
|
)
|
||
|
import Data.OpenApi qualified as OpenApi
|
||
|
import Data.OpenApi.Declare (undeclare)
|
||
|
import Data.Proxy (Proxy (..))
|
||
|
import Hasura.Metadata.DTO.Metadata (MetadataDTO)
|
||
|
import Hasura.Metadata.DTO.MetadataV1 (MetadataV1)
|
||
|
import Hasura.Metadata.DTO.MetadataV2 (MetadataV2)
|
||
|
import Hasura.Metadata.DTO.MetadataV3 (MetadataV3)
|
||
|
import Hasura.Prelude
|
||
|
|
||
|
-- | An OpenApi document includes \"schemas\" that describe the data that may be
|
||
|
-- produced or consumed by an API. It can also include \"paths\" which describe
|
||
|
-- REST endpoints, and the document can include other API metadata. This example
|
||
|
-- only includes schemas.
|
||
|
--
|
||
|
-- Throws an error if any schema listed in 'openApiSchemas' does not have
|
||
|
-- a name.
|
||
|
--
|
||
|
-- The OpenAPI specification for metadata is experimental and incomplete. Please
|
||
|
-- do not incorporate it into essential workflows at this time.
|
||
|
metadataOpenAPI :: OpenApi
|
||
|
metadataOpenAPI =
|
||
|
(mempty :: OpenApi)
|
||
|
& components . schemas .~ HM.fromList (applySchemaName <$> openApiSchemas)
|
||
|
|
||
|
-- | All metadata DTOs should be listed here. Schemas in this list must be
|
||
|
-- named! Some autodocodec combinators apply names for you, like 'object'.
|
||
|
-- Otherwise you can use the 'named' combinator to apply a name.
|
||
|
--
|
||
|
-- As far as I can tell it is necessary to explicitly list all of the data
|
||
|
-- types that should be included in the OpenApi document with their names. It
|
||
|
-- would be nice to provide only a top-level type ('Metadata' in this case), and
|
||
|
-- have all of the types referenced by that type included automatically; but
|
||
|
-- I haven't seen a way to do that.
|
||
|
openApiSchemas :: [OpenApi.NamedSchema]
|
||
|
openApiSchemas =
|
||
|
[ toNamedSchema (Proxy @MetadataDTO),
|
||
|
toNamedSchema (Proxy @MetadataV1),
|
||
|
toNamedSchema (Proxy @MetadataV2),
|
||
|
toNamedSchema (Proxy @MetadataV3)
|
||
|
]
|
||
|
|
||
|
-- | Introspect a given 'OpenApi.NamedSchema' to get its name, and return the
|
||
|
-- name with the unwrapped schema. (NamedSchema wraps a pair of an
|
||
|
-- 'OpenApi.Schema' and an optional name.)
|
||
|
--
|
||
|
-- Throws an exception if the named schema has no name. If this happens to you
|
||
|
-- then use autodocodec's 'named' combinator to apply a name to your codec.
|
||
|
applySchemaName :: OpenApi.NamedSchema -> (Text, OpenApi.Schema)
|
||
|
applySchemaName givenSchema = (schemaName, givenSchema ^. schema)
|
||
|
where
|
||
|
schemaName = case givenSchema ^. name of
|
||
|
Just n -> n
|
||
|
Nothing ->
|
||
|
error $
|
||
|
"a codec listed in 'openApiSchemas' does not have a name; "
|
||
|
<> "use the 'named' combinator from autodocodec to apply a name "
|
||
|
<> "to any codec in that list that does not already have one"
|
||
|
|
||
|
toNamedSchema :: HasCodec a => Proxy a -> OpenApi.NamedSchema
|
||
|
toNamedSchema proxy = undeclare $ declareNamedSchemaViaCodec proxy
|