Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPB-4240: Migrate from swagger2 to openapi3 #3570

Merged
merged 20 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9644e2d
WPB-4240: Initial work on the bulk of the updates. Now onto harder pa…
lepsa Sep 5, 2023
c6e8fce
WPB-4240: Commiting WIP while I investigate a possible GHC bug.
lepsa Sep 5, 2023
fcfd322
Fixed the compiler bug, back onto the changeover from swagger2 to ope…
lepsa Sep 6, 2023
db242d7
WPB-4240: Fixing up fedcalls and working around limitations in openapi3
lepsa Sep 8, 2023
1aa191d
WPB-4240: Adding changelogs
lepsa Sep 8, 2023
853388b
WPB-4240: Small things picked up while going over the PR diff
lepsa Sep 8, 2023
6475781
Merge branch 'develop' into WPB-4240
lepsa Sep 8, 2023
9fb85a2
Merge remote-tracking branch 'origin/develop' into WPB-4240
lepsa Sep 11, 2023
ea158d0
A working version, with a few dodgy fixes that need to be removed.
lepsa Sep 12, 2023
a986ead
Small code cleanup
lepsa Sep 13, 2023
9c2e198
Merge remote-tracking branch 'origin/develop' into WPB-4240
lepsa Sep 13, 2023
1890bd9
More small fixes, and using a patched version of servant-openapi3
lepsa Sep 13, 2023
7678c62
Stripping default responses, 400 and 404, from OpenApi output
lepsa Sep 13, 2023
732e587
WPB-4240: Fixing remaining issues with the schemas of error types
lepsa Sep 14, 2023
3860643
Merge remote-tracking branch 'origin/develop' into WPB-4240
lepsa Sep 14, 2023
1c1ac85
WPB-4240: Adding comments to nix
lepsa Sep 14, 2023
e376fd2
WPB-4240: Adding deprecated flags to API routes and types.
lepsa Sep 19, 2023
8a755cd
Merge branch 'develop' into WPB-4240
elland Sep 19, 2023
faec810
Removed redundant import
elland Sep 19, 2023
74fe785
Updated API description for consistency
elland Sep 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/4-docs/WPB-4240
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Updating the route documentation from Swagger 2 to OpenAPI 3.
4 changes: 4 additions & 0 deletions changelog.d/5-internal/WPB-4240
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Updating the route documentation library from swagger2 to openapi3.

This also introduced a breaking change in how we track what federation calls each route makes.
The openapi3 library doesn't support extension fields, and as such tags are being used instead in a similar way.
2 changes: 1 addition & 1 deletion libs/brig-types/brig-types.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ test-suite brig-types-tests
, brig-types
, bytestring-conversion >=0.3.1
, imports
, openapi3
, QuickCheck >=2.9
, swagger2 >=2.5
, tasty
, tasty-hunit
, tasty-quickcheck
Expand Down
4 changes: 2 additions & 2 deletions libs/brig-types/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
, gitignoreSource
, imports
, lib
, openapi3
, QuickCheck
, swagger2
, tasty
, tasty-hunit
, tasty-quickcheck
Expand Down Expand Up @@ -47,8 +47,8 @@ mkDerivation {
base
bytestring-conversion
imports
openapi3
QuickCheck
swagger2
tasty
tasty-hunit
tasty-quickcheck
Expand Down
4 changes: 2 additions & 2 deletions libs/brig-types/test/unit/Test/Brig/Roundtrip.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ module Test.Brig.Roundtrip where
import Data.Aeson (FromJSON, ToJSON, parseJSON, toJSON)
import Data.Aeson.Types (parseEither)
import Data.ByteString.Conversion
import Data.Swagger (ToSchema, validatePrettyToJSON)
import Data.OpenApi (ToSchema, validatePrettyToJSON)
import Imports
import Test.Tasty (TestTree)
import Test.Tasty.QuickCheck (Arbitrary, counterexample, testProperty, (.&&.), (===))
Expand All @@ -40,7 +40,7 @@ testRoundTrip = testProperty msg trip

testRoundTripWithSwagger ::
forall a.
(Arbitrary a, Typeable a, ToJSON a, FromJSON a, ToSchema a, Eq a, Show a) =>
(Arbitrary a, ToJSON a, FromJSON a, ToSchema a, Eq a, Show a) =>
TestTree
testRoundTripWithSwagger = testProperty msg (trip .&&. scm)
where
Expand Down
4 changes: 2 additions & 2 deletions libs/deriving-swagger2/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
, gitignoreSource
, imports
, lib
, swagger2
, openapi3
}:
mkDerivation {
pname = "deriving-swagger2";
version = "0.1.0";
src = gitignoreSource ./.;
libraryHaskellDepends = [ base extra imports swagger2 ];
libraryHaskellDepends = [ base extra imports openapi3 ];
license = lib.licenses.agpl3Only;
}
4 changes: 2 additions & 2 deletions libs/deriving-swagger2/deriving-swagger2.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ library
-Wredundant-constraints -Wunused-packages

build-depends:
base >=4 && <5
base >=4 && <5
, extra
, imports
, swagger2 >=0.6
, openapi3

default-language: GHC2021
18 changes: 7 additions & 11 deletions libs/deriving-swagger2/src/Deriving/Swagger.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{-# LANGUAGE RankNTypes #-}

-- This file is part of the Wire Server implementation.
--
-- Copyright (C) 2022 Wire Swiss GmbH <opensource@wire.com>
Expand All @@ -22,10 +24,10 @@ module Deriving.Swagger where
import Data.Char qualified as Char
import Data.Kind (Constraint)
import Data.List.Extra (stripSuffix)
import Data.OpenApi.Internal.Schema (GToSchema)
import Data.OpenApi.Internal.TypeShape
import Data.OpenApi.Schema
import Data.Proxy (Proxy (..))
import Data.Swagger (SchemaOptions, ToSchema (..), constructorTagModifier, defaultSchemaOptions, fieldLabelModifier, genericDeclareNamedSchema)
import Data.Swagger.Internal.Schema (GToSchema)
import Data.Swagger.Internal.TypeShape (TypeHasSimpleShape)
import GHC.Generics (Generic (Rep))
import GHC.TypeLits (ErrorMessage (Text), KnownSymbol, Symbol, TypeError, symbolVal)
import Imports
Expand Down Expand Up @@ -81,6 +83,7 @@ import Imports
-- | A newtype wrapper which gives ToSchema instances with modified options.
-- 't' has to have an instance of the 'SwaggerOptions' class.
newtype CustomSwagger t a = CustomSwagger {unCustomSwagger :: a}
deriving (Generic, Typeable)

class SwaggerOptions xs where
swaggerOptions :: SchemaOptions
Expand All @@ -94,14 +97,7 @@ instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (FieldLabelModi
instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (ConstructorTagModifier f ': xs) where
swaggerOptions = (swaggerOptions @xs) {constructorTagModifier = getStringModifier @f}

instance
( SwaggerOptions t,
Generic a,
GToSchema (Rep a),
TypeHasSimpleShape a "genericDeclareNamedSchemaUnrestricted"
) =>
ToSchema (CustomSwagger t a)
where
instance (SwaggerOptions t, Generic a, Typeable a, GToSchema (Rep a), Typeable (CustomSwagger t a), TypeHasSimpleShape a "genericDeclareNamedSchemaUnrestricted") => ToSchema (CustomSwagger t a) where
declareNamedSchema _ = genericDeclareNamedSchema (swaggerOptions @t) (Proxy @a)

-- ** Specify __what__ to modify
Expand Down
4 changes: 2 additions & 2 deletions libs/extended/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
, servant
, servant-client
, servant-client-core
, servant-openapi3
, servant-server
, servant-swagger
, temporary
, text
, tinylog
Expand Down Expand Up @@ -60,8 +60,8 @@ mkDerivation {
servant
servant-client
servant-client-core
servant-openapi3
servant-server
servant-swagger
text
tinylog
unliftio
Expand Down
2 changes: 1 addition & 1 deletion libs/extended/extended.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ library
, servant
, servant-client
, servant-client-core
, servant-openapi3
, servant-server
, servant-swagger
, text
, tinylog
, unliftio
Expand Down
8 changes: 4 additions & 4 deletions libs/extended/src/Servant/API/Extended.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import Network.Wai
import Servant.API
import Servant.API.ContentTypes
import Servant.API.Modifiers
import Servant.OpenApi
import Servant.Server.Internal
import Servant.Swagger
import Prelude ()

-- | Like 'ReqBody'', but takes parsers that throw 'ServerError', not 'String'. @tag@ is used
Expand Down Expand Up @@ -108,10 +108,10 @@ instance
Right v -> pure v

instance
HasSwagger (ReqBody' '[Required, Strict] cts a :> api) =>
HasSwagger (ReqBodyCustomError cts tag a :> api)
HasOpenApi (ReqBody' '[Required, Strict] cts a :> api) =>
HasOpenApi (ReqBodyCustomError cts tag a :> api)
where
toSwagger Proxy = toSwagger (Proxy @(ReqBody' '[Required, Strict] cts a :> api))
toOpenApi Proxy = toOpenApi (Proxy @(ReqBody' '[Required, Strict] cts a :> api))

instance RoutesToPaths rest => RoutesToPaths (ReqBodyCustomError' mods list tag a :> rest) where
getRoutes = getRoutes @rest
6 changes: 3 additions & 3 deletions libs/extended/src/Servant/API/Extended/RawM.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import Data.Proxy
import Imports
import Network.Wai
import Servant.API (Raw)
import Servant.OpenApi
import Servant.Server hiding (respond)
import Servant.Server.Internal.Delayed
import Servant.Server.Internal.RouteResult
import Servant.Server.Internal.Router
import Servant.Swagger

type ApplicationM m = Request -> (Response -> IO ResponseReceived) -> m ResponseReceived

Expand Down Expand Up @@ -51,8 +51,8 @@ instance HasServer RawM context where

hoistServerWithContext _ _ f srvM req respond = f (srvM req respond)

instance HasSwagger RawM where
toSwagger _ = toSwagger (Proxy @Raw)
instance HasOpenApi RawM where
toOpenApi _ = toOpenApi (Proxy @Raw)

instance RoutesToPaths RawM where
getRoutes = []
6 changes: 3 additions & 3 deletions libs/schema-profunctor/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
, insert-ordered-containers
, lens
, lib
, openapi3
, profunctors
, swagger2
, tasty
, tasty-hunit
, text
Expand All @@ -34,8 +34,8 @@ mkDerivation {
containers
imports
lens
openapi3
profunctors
swagger2
text
transformers
vector
Expand All @@ -47,7 +47,7 @@ mkDerivation {
imports
insert-ordered-containers
lens
swagger2
openapi3
tasty
tasty-hunit
text
Expand Down
4 changes: 2 additions & 2 deletions libs/schema-profunctor/schema-profunctor.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ library
, containers
, imports
, lens
, openapi3
, profunctors
, swagger2 >=2 && <2.9
, text
, transformers
, vector
Expand Down Expand Up @@ -139,8 +139,8 @@ test-suite schemas-tests
, imports
, insert-ordered-containers
, lens
, openapi3
, schema-profunctor
, swagger2
, tasty
, tasty-hunit
, text
Expand Down
34 changes: 20 additions & 14 deletions libs/schema-profunctor/src/Data/Schema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,11 @@ import Data.List.NonEmpty (NonEmpty)
import Data.List.NonEmpty qualified as NonEmpty
import Data.Map qualified as Map
import Data.Monoid hiding (Product)
import Data.OpenApi qualified as S
import Data.OpenApi.Declare qualified as S
import Data.Profunctor (Star (..))
import Data.Proxy (Proxy (..))
import Data.Set qualified as Set
import Data.Swagger qualified as S
import Data.Swagger.Declare qualified as S
import Data.Swagger.Internal qualified as S
import Data.Text qualified as T
import Data.Text.Lazy qualified as TL
import Data.Vector qualified as V
Expand Down Expand Up @@ -624,7 +623,7 @@ text name =
(A.withText (T.unpack name) pure)
(pure . A.String)
where
d = mempty & S.type_ ?~ S.SwaggerString
d = mempty & S.type_ ?~ S.OpenApiString

-- | A schema for a textual value with possible failure.
parsedText ::
Expand Down Expand Up @@ -764,7 +763,7 @@ instance HasSchemaRef doc => HasField doc SwaggerDoc where
where
f ref =
mempty
& S.type_ ?~ S.SwaggerObject
& S.type_ ?~ S.OpenApiObject
& S.properties . at name ?~ ref
& S.required .~ [name]

Expand All @@ -780,16 +779,16 @@ instance HasSchemaRef ndoc => HasArray ndoc SwaggerDoc where
f :: S.Referenced S.Schema -> S.Schema
f ref =
mempty
& S.type_ ?~ S.SwaggerArray
& S.items ?~ S.SwaggerItemsObject ref
& S.type_ ?~ S.OpenApiArray
& S.items ?~ S.OpenApiItemsObject ref

instance HasSchemaRef ndoc => HasMap ndoc SwaggerDoc where
mkMap = fmap f . schemaRef
where
f :: S.Referenced S.Schema -> S.Schema
f ref =
mempty
& S.type_ ?~ S.SwaggerObject
& S.type_ ?~ S.OpenApiObject
& S.additionalProperties ?~ S.AdditionalPropertiesSchema ref

class HasMinItems s a where
Expand All @@ -799,19 +798,19 @@ instance HasMinItems SwaggerDoc (Maybe Integer) where
minItems = declared . S.minItems

instance HasEnum Text NamedSwaggerDoc where
mkEnum = mkSwaggerEnum S.SwaggerString
mkEnum = mkSwaggerEnum S.OpenApiString

instance HasEnum Integer NamedSwaggerDoc where
mkEnum = mkSwaggerEnum S.SwaggerInteger
mkEnum = mkSwaggerEnum S.OpenApiInteger

instance HasEnum Natural NamedSwaggerDoc where
mkEnum = mkSwaggerEnum S.SwaggerInteger
mkEnum = mkSwaggerEnum S.OpenApiInteger

instance HasEnum Bool NamedSwaggerDoc where
mkEnum = mkSwaggerEnum S.SwaggerBoolean
mkEnum = mkSwaggerEnum S.OpenApiBoolean

mkSwaggerEnum ::
S.SwaggerType 'S.SwaggerKindSchema ->
S.OpenApiType ->
Text ->
[A.Value] ->
NamedSwaggerDoc
Expand Down Expand Up @@ -839,11 +838,12 @@ class ToSchema a where
-- Newtype wrappers for deriving via

newtype Schema a = Schema {getSchema :: a}
deriving (Generic)

schemaToSwagger :: forall a. ToSchema a => Proxy a -> Declare S.NamedSchema
schemaToSwagger _ = runDeclare (schemaDoc (schema @a))

instance ToSchema a => S.ToSchema (Schema a) where
instance (Typeable a, ToSchema a) => S.ToSchema (Schema a) where
declareNamedSchema _ = schemaToSwagger (Proxy @a)

-- | JSON serialiser for an instance of 'ToSchema'.
Expand Down Expand Up @@ -920,8 +920,14 @@ instance S.HasSchema d S.Schema => S.HasSchema (SchemaP d v w a b) S.Schema wher
instance S.HasDescription NamedSwaggerDoc (Maybe Text) where
description = declared . S.schema . S.description

instance S.HasDeprecated NamedSwaggerDoc (Maybe Bool) where
deprecated = declared . S.schema . S.deprecated

instance {-# OVERLAPPABLE #-} S.HasDescription s a => S.HasDescription (WithDeclare s) a where
description = declared . S.description

instance {-# OVERLAPPABLE #-} S.HasDeprecated s a => S.HasDeprecated (WithDeclare s) a where
deprecated = declared . S.deprecated

instance {-# OVERLAPPABLE #-} S.HasExample s a => S.HasExample (WithDeclare s) a where
example = declared . S.example
Loading
Loading