diff --git a/changelog.d/1-api-changes/introduce-v5 b/changelog.d/1-api-changes/introduce-v5
new file mode 100644
index 0000000000..0d2498b3d3
--- /dev/null
+++ b/changelog.d/1-api-changes/introduce-v5
@@ -0,0 +1 @@
+Introduce v5 development version
diff --git a/docs/src/developer/developer/api-versioning.md b/docs/src/developer/developer/api-versioning.md
index 053c830749..3cf3613454 100644
--- a/docs/src/developer/developer/api-versioning.md
+++ b/docs/src/developer/developer/api-versioning.md
@@ -110,8 +110,7 @@ are several steps to make apart from deciding what endpoint changes are part of
the version:
- In `wire-api` extend the `Version` type with a new version by appending the
- new version to the end, e.g., by adding `V4`. Make sure to update its
- `ToSchema` instance,
+ new version to the end, e.g., by adding `V4`.
- In the same `Version` module update the `developmentVersions` value to list
only the new version,
- Consider updating the `backendApiVersion` value in Stern, which is
diff --git a/integration/test/Test/Brig.hs b/integration/test/Test/Brig.hs
index 98e046fa6d..3380d8400c 100644
--- a/integration/test/Test/Brig.hs
+++ b/integration/test/Test/Brig.hs
@@ -139,7 +139,7 @@ testCrudOAuthClient = do
testSwagger :: HasCallStack => App ()
testSwagger = do
let existingVersions :: [Int]
- existingVersions = [0, 1, 2, 3, 4]
+ existingVersions = [0, 1, 2, 3, 4, 5]
internalApis :: [String]
internalApis = ["brig", "cannon", "cargohold", "cannon", "spar"]
diff --git a/libs/wire-api/src/Wire/API/Error.hs b/libs/wire-api/src/Wire/API/Error.hs
index 1edf2eda32..304f11596e 100644
--- a/libs/wire-api/src/Wire/API/Error.hs
+++ b/libs/wire-api/src/Wire/API/Error.hs
@@ -68,6 +68,7 @@ import Servant
import Servant.Swagger
import Wire.API.Routes.MultiVerb
import Wire.API.Routes.Named (Named)
+import Wire.API.Routes.Version
-- | Runtime representation of a statically-known error.
data DynError = DynError
@@ -167,6 +168,10 @@ instance RoutesToPaths api => RoutesToPaths (CanThrow err :> api) where
instance RoutesToPaths api => RoutesToPaths (CanThrowMany errs :> api) where
getRoutes = getRoutes @api
+type instance
+ SpecialiseToVersion v (CanThrow e :> api) =
+ CanThrow e :> SpecialiseToVersion v api
+
instance (HasServer api ctx) => HasServer (CanThrow e :> api) ctx where
type ServerT (CanThrow e :> api) m = ServerT api m
@@ -185,6 +190,10 @@ instance
where
toSwagger _ = addToSwagger @e (toSwagger (Proxy @api))
+type instance
+ SpecialiseToVersion v (CanThrowMany es :> api) =
+ CanThrowMany es :> SpecialiseToVersion v api
+
instance HasSwagger api => HasSwagger (CanThrowMany '() :> api) where
toSwagger _ = toSwagger (Proxy @api)
diff --git a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs
index f1f571106a..fbc133d672 100644
--- a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs
+++ b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs
@@ -48,6 +48,7 @@ import Servant.Swagger
import Test.QuickCheck (Arbitrary)
import TransitiveAnns.Types
import Unsafe.Coerce (unsafeCoerce)
+import Wire.API.Routes.Version
import Wire.Arbitrary (GenericUniform (..))
-- | This function exists only to provide a convenient place for the
@@ -151,6 +152,10 @@ type family ShowComponent (x :: Component) = (res :: Symbol) | res -> x where
ShowComponent 'Galley = "galley"
ShowComponent 'Cargohold = "cargohold"
+type instance
+ SpecialiseToVersion v (MakesFederatedCall comp name :> api) =
+ MakesFederatedCall comp name :> SpecialiseToVersion v api
+
-- | 'MakesFederatedCall' annotates the swagger documentation with an extension
-- tag @x-wire-makes-federated-calls-to@.
instance (HasSwagger api, KnownSymbol name, KnownSymbol (ShowComponent comp)) => HasSwagger (MakesFederatedCall comp name :> api :: Type) where
diff --git a/libs/wire-api/src/Wire/API/Routes/API.hs b/libs/wire-api/src/Wire/API/Routes/API.hs
index 607933e2ed..b43569bf76 100644
--- a/libs/wire-api/src/Wire/API/Routes/API.hs
+++ b/libs/wire-api/src/Wire/API/Routes/API.hs
@@ -16,7 +16,8 @@
-- with this program. If not, see .
module Wire.API.Routes.API
- ( API,
+ ( ServiceAPI (..),
+ API,
hoistAPIHandler,
hoistAPI,
mkAPI,
@@ -29,14 +30,28 @@ module Wire.API.Routes.API
where
import Data.Domain
+import Data.Kind
import Data.Proxy
+import Data.Swagger qualified as S
import Imports
import Polysemy
import Polysemy.Error
import Polysemy.Internal
import Servant hiding (Union)
+import Servant.Swagger
import Wire.API.Error
import Wire.API.Routes.Named
+import Wire.API.Routes.Version
+
+class ServiceAPI service (v :: Version) where
+ type ServiceAPIRoutes service
+ type SpecialisedAPIRoutes v service :: Type
+ type SpecialisedAPIRoutes v service = SpecialiseToVersion v (ServiceAPIRoutes service)
+ serviceSwagger :: HasSwagger (SpecialisedAPIRoutes v service) => S.Swagger
+ serviceSwagger = toSwagger (Proxy @(SpecialisedAPIRoutes v service))
+
+instance ServiceAPI VersionAPITag v where
+ type ServiceAPIRoutes VersionAPITag = VersionAPI
-- | A Servant handler on a polysemy stack. This is used to help with type inference.
newtype API api r = API {unAPI :: ServerT api (Sem r)}
diff --git a/libs/wire-api/src/Wire/API/Routes/Bearer.hs b/libs/wire-api/src/Wire/API/Routes/Bearer.hs
index b2b0c1918e..545db5254d 100644
--- a/libs/wire-api/src/Wire/API/Routes/Bearer.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Bearer.hs
@@ -26,6 +26,7 @@ import Data.Text.Encoding qualified as T
import Imports
import Servant
import Servant.Swagger
+import Wire.API.Routes.Version
newtype Bearer a = Bearer {unBearer :: a}
@@ -42,6 +43,10 @@ type BearerQueryParam =
[Lenient, Description "Access token"]
"access_token"
+type instance
+ SpecialiseToVersion v (Bearer a :> api) =
+ Bearer a :> SpecialiseToVersion v api
+
instance HasSwagger api => HasSwagger (Bearer a :> api) where
toSwagger _ =
toSwagger (Proxy @api)
diff --git a/libs/wire-api/src/Wire/API/Routes/Cookies.hs b/libs/wire-api/src/Wire/API/Routes/Cookies.hs
index 644435d205..10383904cc 100644
--- a/libs/wire-api/src/Wire/API/Routes/Cookies.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Cookies.hs
@@ -29,6 +29,7 @@ import Imports
import Servant
import Servant.Swagger
import Web.Cookie (parseCookies)
+import Wire.API.Routes.Version
data (:::) a b
@@ -58,6 +59,10 @@ newtype CookieTuple cs = CookieTuple {unCookieTuple :: NP I (CookieTypes cs)}
type CookieMap = Map ByteString (NonEmpty ByteString)
+type instance
+ SpecialiseToVersion v (Cookies cs :> api) =
+ Cookies cs :> SpecialiseToVersion v api
+
instance HasSwagger api => HasSwagger (Cookies cs :> api) where
toSwagger _ = toSwagger (Proxy @api)
diff --git a/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs b/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs
index 209afbf64a..d9287bd5fa 100644
--- a/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs
+++ b/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs
@@ -37,6 +37,7 @@ import Servant.Server hiding (respond)
import Servant.Server.Internal
import Servant.Swagger as S
import Servant.Swagger.Internal as S
+import Wire.API.Routes.Version
-- FUTUREWORK: make it possible to generate headers at runtime
data LowLevelStream method status (headers :: [(Symbol, Symbol)]) desc ctype
@@ -84,6 +85,10 @@ instance
status = statusFromNat (Proxy :: Proxy status)
extraHeaders = renderHeaders @headers
+type instance
+ SpecialiseToVersion v (LowLevelStream m s h d t) =
+ LowLevelStream m s h d t
+
instance
(Accept ctype, KnownNat status, KnownSymbol desc, SwaggerMethod method) =>
HasSwagger (LowLevelStream method status headers desc ctype)
diff --git a/libs/wire-api/src/Wire/API/Routes/Public.hs b/libs/wire-api/src/Wire/API/Routes/Public.hs
index befd085500..8ad302b6dd 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public.hs
@@ -55,6 +55,7 @@ import Servant.Server.Internal.DelayedIO
import Servant.Server.Internal.Router (Router)
import Servant.Swagger (HasSwagger (toSwagger))
import Wire.API.OAuth qualified as OAuth
+import Wire.API.Routes.Version
mapRequestArgument ::
forall mods a b.
@@ -196,20 +197,29 @@ type ZOptHostHeader =
instance HasSwagger api => HasSwagger (ZHostOpt :> api) where
toSwagger _ = toSwagger (Proxy @api)
+type instance SpecialiseToVersion v (ZHostOpt :> api) = ZHostOpt :> SpecialiseToVersion v api
+
+addZAuthSwagger :: Swagger -> Swagger
+addZAuthSwagger s =
+ s
+ & securityDefinitions <>~ SecurityDefinitions (InsOrdHashMap.singleton "ZAuth" secScheme)
+ & security <>~ [SecurityRequirement $ InsOrdHashMap.singleton "ZAuth" []]
+ where
+ secScheme =
+ SecurityScheme
+ { _securitySchemeType = SecuritySchemeApiKey (ApiKeyParams "Authorization" ApiKeyHeader),
+ _securitySchemeDescription = Just "Must be a token retrieved by calling 'POST /login' or 'POST /access'. It must be presented in this format: 'Bearer \\'."
+ }
+
+type instance
+ SpecialiseToVersion v (ZAuthServant t opts :> api) =
+ ZAuthServant t opts :> SpecialiseToVersion v api
+
instance HasSwagger api => HasSwagger (ZAuthServant 'ZAuthUser _opts :> api) where
- toSwagger _ =
- toSwagger (Proxy @api)
- & securityDefinitions <>~ SecurityDefinitions (InsOrdHashMap.singleton "ZAuth" secScheme)
- & security <>~ [SecurityRequirement $ InsOrdHashMap.singleton "ZAuth" []]
- where
- secScheme =
- SecurityScheme
- { _securitySchemeType = SecuritySchemeApiKey (ApiKeyParams "Authorization" ApiKeyHeader),
- _securitySchemeDescription = Just "Must be a token retrieved by calling 'POST /login' or 'POST /access'. It must be presented in this format: 'Bearer \\'."
- }
+ toSwagger _ = addZAuthSwagger (toSwagger (Proxy @api))
instance HasSwagger api => HasSwagger (ZAuthServant 'ZLocalAuthUser opts :> api) where
- toSwagger _ = toSwagger (Proxy @(ZAuthServant 'ZAuthUser opts :> api))
+ toSwagger _ = addZAuthSwagger (toSwagger (Proxy @api))
instance HasLink endpoint => HasLink (ZAuthServant usr opts :> endpoint) where
type MkLink (ZAuthServant _ _ :> endpoint) a = MkLink endpoint a
@@ -286,11 +296,18 @@ instance ToSchema a => ToSchema (Headers ls a) where
data DescriptionOAuthScope (scope :: OAuth.OAuthScope)
-instance (HasSwagger api, OAuth.IsOAuthScope scope) => HasSwagger (DescriptionOAuthScope scope :> api) where
- toSwagger _ = toSwagger (Proxy @api) & addScopeDescription
- where
- addScopeDescription :: Swagger -> Swagger
- addScopeDescription = allOperations . description %~ Just . (<> "\nOAuth scope: `" <> cs (toByteString (OAuth.toOAuthScope @scope)) <> "`") . fold
+type instance
+ SpecialiseToVersion v (DescriptionOAuthScope scope :> api) =
+ DescriptionOAuthScope scope :> SpecialiseToVersion v api
+
+instance
+ (HasSwagger api, OAuth.IsOAuthScope scope) =>
+ HasSwagger (DescriptionOAuthScope scope :> api)
+ where
+ toSwagger _ = addScopeDescription @scope (toSwagger (Proxy @api))
+
+addScopeDescription :: forall scope. OAuth.IsOAuthScope scope => Swagger -> Swagger
+addScopeDescription = allOperations . description %~ Just . (<> "\nOAuth scope: `" <> cs (toByteString (OAuth.toOAuthScope @scope)) <> "`") . fold
instance (HasServer api ctx) => HasServer (DescriptionOAuthScope scope :> api) ctx where
type ServerT (DescriptionOAuthScope scope :> api) m = ServerT api m
diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs
index ceec7e951c..b99aa0e729 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs
@@ -39,7 +39,6 @@ import Imports hiding (head)
import Network.Wai.Utilities
import Servant (JSON)
import Servant hiding (Handler, JSON, addHeader, respond)
-import Servant.Swagger (HasSwagger (toSwagger))
import Servant.Swagger.Internal.Orphans ()
import Wire.API.Call.Config (RTCConfiguration)
import Wire.API.Connection hiding (MissingLegalholdConsent)
@@ -51,6 +50,7 @@ import Wire.API.MLS.Servant
import Wire.API.MakesFederatedCall
import Wire.API.OAuth
import Wire.API.Properties
+import Wire.API.Routes.API
import Wire.API.Routes.Bearer
import Wire.API.Routes.Cookies
import Wire.API.Routes.MultiVerb
@@ -93,8 +93,10 @@ type BrigAPI =
:<|> SystemSettingsAPI
:<|> OAuthAPI
-brigSwagger :: Swagger
-brigSwagger = toSwagger (Proxy @BrigAPI)
+data BrigAPITag
+
+instance ServiceAPI BrigAPITag v where
+ type ServiceAPIRoutes BrigAPITag = BrigAPI
-------------------------------------------------------------------------------
-- User API
diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig/OAuth.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig/OAuth.hs
index 2a37bd71c6..0a4adf5240 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public/Brig/OAuth.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig/OAuth.hs
@@ -19,14 +19,13 @@ module Wire.API.Routes.Public.Brig.OAuth where
import Data.Id as Id
import Data.SOP
-import Data.Swagger (Swagger)
import Imports hiding (exp, head)
import Servant (JSON)
import Servant hiding (Handler, JSON, Tagged, addHeader, respond)
-import Servant.Swagger
import Servant.Swagger.Internal.Orphans ()
import Wire.API.Error
import Wire.API.OAuth
+import Wire.API.Routes.API
import Wire.API.Routes.MultiVerb
import Wire.API.Routes.Named (Named (..))
import Wire.API.Routes.Public
@@ -156,5 +155,7 @@ instance AsUnion CreateOAuthAuthorizationCodeResponses CreateOAuthCodeResponse w
fromUnion (S (S (S (S (Z (I _)))))) = CreateOAuthCodeRedirectUrlMissMatch
fromUnion (S (S (S (S (S x))))) = case x of {}
-swaggerDoc :: Swagger
-swaggerDoc = toSwagger (Proxy @OAuthAPI)
+data OAuthAPITag
+
+instance ServiceAPI OAuthAPITag v where
+ type ServiceAPIRoutes OAuthAPITag = OAuthAPI
diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Cannon.hs b/libs/wire-api/src/Wire/API/Routes/Public/Cannon.hs
index ceacf45518..eda1f01a8e 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public/Cannon.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public/Cannon.hs
@@ -18,14 +18,13 @@
module Wire.API.Routes.Public.Cannon where
import Data.Id
-import Data.Swagger
import Servant
-import Servant.Swagger
+import Wire.API.Routes.API
import Wire.API.Routes.Named
import Wire.API.Routes.Public (ZConn, ZUser)
import Wire.API.Routes.WebSocket
-type PublicAPI =
+type CannonAPI =
Named
"await-notifications"
( Summary "Establish websocket connection"
@@ -43,5 +42,7 @@ type PublicAPI =
:> WebSocketPending
)
-swaggerDoc :: Swagger
-swaggerDoc = toSwagger (Proxy @PublicAPI)
+data CannonAPITag
+
+instance ServiceAPI CannonAPITag v where
+ type ServiceAPIRoutes CannonAPITag = CannonAPI
diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs b/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs
index 2260d3953e..1ce9dd600c 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs
@@ -22,16 +22,15 @@ import Data.Kind
import Data.Metrics.Servant
import Data.Qualified
import Data.SOP
-import Data.Swagger qualified as Swagger
import Imports
import Servant
-import Servant.Swagger.Internal
import Servant.Swagger.Internal.Orphans ()
import URI.ByteString
import Wire.API.Asset
import Wire.API.Error
import Wire.API.Error.Cargohold
import Wire.API.MakesFederatedCall
+import Wire.API.Routes.API
import Wire.API.Routes.AssetBody
import Wire.API.Routes.MultiVerb
import Wire.API.Routes.Public
@@ -56,8 +55,9 @@ type instance ApplyPrincipalPath 'BotPrincipalTag api = ZBot :> "bot" :> "assets
type instance ApplyPrincipalPath 'ProviderPrincipalTag api = ZProvider :> "provider" :> "assets" :> api
-instance HasSwagger (ApplyPrincipalPath tag api) => HasSwagger (tag :> api) where
- toSwagger _ = toSwagger (Proxy @(ApplyPrincipalPath tag api))
+type instance
+ SpecialiseToVersion v ((tag :: PrincipalTag) :> api) =
+ SpecialiseToVersion v (ApplyPrincipalPath tag api)
instance HasServer (ApplyPrincipalPath tag api) ctx => HasServer (tag :> api) ctx where
type ServerT (tag :> api) m = ServerT (ApplyPrincipalPath tag api) m
@@ -90,7 +90,7 @@ type GetAsset =
'[ErrorResponse 'AssetNotFound, AssetRedirect]
(Maybe (AssetLocation Absolute))
-type ServantAPI =
+type CargoholdAPI =
( Summary "Renew an asset token"
:> Until 'V2
:> CanThrow 'AssetNotFound
@@ -315,5 +315,7 @@ type MainAPI =
()
)
-swaggerDoc :: Swagger.Swagger
-swaggerDoc = toSwagger (Proxy @ServantAPI)
+data CargoholdAPITag
+
+instance ServiceAPI CargoholdAPITag v where
+ type ServiceAPIRoutes CargoholdAPITag = CargoholdAPI
diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs
index ff1b80fe0b..d24c473738 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs
@@ -20,11 +20,9 @@
module Wire.API.Routes.Public.Galley where
-import Data.SOP
-import Data.Swagger qualified as Swagger
import Servant hiding (WithStatus)
-import Servant.Swagger.Internal
import Servant.Swagger.Internal.Orphans ()
+import Wire.API.Routes.API
import Wire.API.Routes.Public.Galley.Bot
import Wire.API.Routes.Public.Galley.Conversation
import Wire.API.Routes.Public.Galley.CustomBackend
@@ -37,7 +35,7 @@ import Wire.API.Routes.Public.Galley.TeamConversation
import Wire.API.Routes.Public.Galley.TeamMember
import Wire.API.Routes.Public.Galley.TeamNotification (TeamNotificationAPI)
-type ServantAPI =
+type GalleyAPI =
ConversationAPI
:<|> TeamConversationAPI
:<|> MessagingAPI
@@ -50,5 +48,7 @@ type ServantAPI =
:<|> TeamMemberAPI
:<|> TeamNotificationAPI
-swaggerDoc :: Swagger.Swagger
-swaggerDoc = toSwagger (Proxy @ServantAPI)
+data GalleyAPITag
+
+instance ServiceAPI GalleyAPITag v where
+ type ServiceAPIRoutes GalleyAPITag = GalleyAPI
diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Gundeck.hs b/libs/wire-api/src/Wire/API/Routes/Public/Gundeck.hs
index 7fad8afba9..b2d0d329da 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public/Gundeck.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public/Gundeck.hs
@@ -19,15 +19,13 @@ module Wire.API.Routes.Public.Gundeck where
import Data.Id (ClientId)
import Data.Range
-import Data.SOP
-import Data.Swagger qualified as Swagger
import Imports
import Servant
-import Servant.Swagger
import Wire.API.Error
import Wire.API.Error.Gundeck as E
import Wire.API.Notification
import Wire.API.Push.V2.Token
+import Wire.API.Routes.API
import Wire.API.Routes.MultiVerb
import Wire.API.Routes.Named
import Wire.API.Routes.Public
@@ -132,5 +130,7 @@ type NotificationAPI =
(Maybe QueuedNotificationList)
)
-swaggerDoc :: Swagger.Swagger
-swaggerDoc = toSwagger (Proxy @GundeckAPI)
+data GundeckAPITag
+
+instance ServiceAPI GundeckAPITag v where
+ type ServiceAPIRoutes GundeckAPITag = GundeckAPI
diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Proxy.hs b/libs/wire-api/src/Wire/API/Routes/Public/Proxy.hs
index 4f507e1635..4fa0e100c8 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public/Proxy.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public/Proxy.hs
@@ -17,11 +17,9 @@
module Wire.API.Routes.Public.Proxy where
-import Data.SOP
-import Data.Swagger qualified as Swagger
import Servant
import Servant.API.Extended.RawM (RawM)
-import Servant.Swagger
+import Wire.API.Routes.API
import Wire.API.Routes.Named
type ProxyAPI =
@@ -50,6 +48,8 @@ type family ProxyAPISummary name where
ProxyAPISummary "gmaps-path" =
"[DEPRECATED] proxy: `get /proxy/googlemaps/maps/api/geocode/:path`; see google maps API docs"
+data ProxyAPITag
+
-- | FUTUREWORK(fisx): (1) the verb could be added to the swagger docs in the appropriate
-- place here; it's always defined in the `Summary`, but the `RawM` doesn't allow to constrain
-- it. (2) there should be a way to make this more type-safe: `assertMethod` in
@@ -58,5 +58,5 @@ type family ProxyAPISummary name where
-- "api" :> "token" :> OnlyMethod "POST" :> RawM`, and then the `ServerT` instance for
-- `OnlyMethod` requires a proxy argument in the handler of the same type. Or something. (am
-- i massifly over-engineering things here?)
-swaggerDoc :: Swagger.Swagger
-swaggerDoc = toSwagger (Proxy @ProxyAPI)
+instance ServiceAPI ProxyAPITag v where
+ type ServiceAPIRoutes ProxyAPITag = ProxyAPI
diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs
index adaf1c3b72..59b98ddc9e 100644
--- a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs
@@ -20,19 +20,19 @@ module Wire.API.Routes.Public.Spar where
import Data.Id
import Data.Proxy
import Data.Range
-import Data.Swagger (Swagger)
import Imports
import SAML2.WebSSO qualified as SAML
import Servant
import Servant.API.Extended
import Servant.Multipart
-import Servant.Swagger (toSwagger)
+import Servant.Swagger
import URI.ByteString qualified as URI
import Web.Scim.Capabilities.MetaSchema as Scim.Meta
import Web.Scim.Class.Auth as Scim.Auth
import Web.Scim.Class.User as Scim.User
import Wire.API.Error
import Wire.API.Error.Brig
+import Wire.API.Routes.API
import Wire.API.Routes.Internal.Spar
import Wire.API.Routes.Public
import Wire.API.SwaggerServant
@@ -45,7 +45,7 @@ import Wire.API.User.Scim
-- FUTUREWORK: use https://hackage.haskell.org/package/servant-0.14.1/docs/Servant-API-Generic.html?
-type API =
+type SparAPI =
"sso" :> APISSO
:<|> "identity-providers" :> APIIDP
:<|> "scim" :> APIScim
@@ -186,5 +186,9 @@ type APIScimTokenDelete =
type APIScimTokenList =
Get '[JSON] ScimTokenList
-swaggerDoc :: Swagger
-swaggerDoc = toSwagger (Proxy @API)
+data SparAPITag
+
+instance ServiceAPI SparAPITag v where
+ type ServiceAPIRoutes SparAPITag = SparAPI
+ type SpecialisedAPIRoutes v SparAPITag = SparAPI
+ serviceSwagger = toSwagger (Proxy @SparAPI)
diff --git a/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs b/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs
index 4fd030267d..f54cccf4f3 100644
--- a/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs
+++ b/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs
@@ -34,6 +34,7 @@ import Servant.API.Modifiers
import Servant.Client.Core.HasClient
import Servant.Server.Internal.ErrorFormatter
import Servant.Swagger
+import Wire.API.Routes.Version
-- | Capture a value qualified by a domain, with modifiers.
data QualifiedCapture' (mods :: [Type]) (capture :: Symbol) (a :: Type)
@@ -50,6 +51,10 @@ type WithDomain mods capture a api =
:> Capture' mods capture a
:> api
+type instance
+ SpecialiseToVersion v (QualifiedCapture' mods capture a :> api) =
+ QualifiedCapture' mods capture a :> SpecialiseToVersion v api
+
instance
( Typeable a,
ToParamSchema a,
diff --git a/libs/wire-api/src/Wire/API/Routes/Version.hs b/libs/wire-api/src/Wire/API/Routes/Version.hs
index 95fba40302..826da8873a 100644
--- a/libs/wire-api/src/Wire/API/Routes/Version.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Version.hs
@@ -22,8 +22,8 @@
module Wire.API.Routes.Version
( -- * API version endpoint
VersionAPI,
+ VersionAPITag,
VersionInfo (..),
- versionSwagger,
versionHeader,
VersionHeader,
@@ -31,11 +31,15 @@ module Wire.API.Routes.Version
Version (..),
VersionNumber (..),
supportedVersions,
+ isDevelopmentVersion,
developmentVersions,
-- * Servant combinators
Until,
From,
+
+ -- * Swagger instances
+ SpecialiseToVersion,
)
where
@@ -49,13 +53,15 @@ import Data.ByteString.Conversion (ToByteString (builder), toByteString')
import Data.ByteString.Lazy qualified as LBS
import Data.Domain
import Data.Schema
-import Data.Singletons.TH
+import Data.Singletons.Base.TH
import Data.Swagger qualified as S
-import Data.Text as Text
+import Data.Text qualified as Text
import Data.Text.Encoding as Text
+import GHC.TypeLits
import Imports
import Servant
-import Servant.Swagger
+import Servant.API.Extended.RawM
+import Wire.API.Routes.MultiVerb
import Wire.API.Routes.Named
import Wire.API.VersionInfo
import Wire.Arbitrary (Arbitrary, GenericUniform (GenericUniform))
@@ -68,7 +74,7 @@ import Wire.Arbitrary (Arbitrary, GenericUniform (GenericUniform))
-- and 'developmentVersions' stay in sync; everything else here should keep working without
-- change. See also documentation in the *docs* directory.
-- https://docs.wire.com/developer/developer/api-versioning.html#version-bump-checklist
-data Version = V0 | V1 | V2 | V3 | V4
+data Version = V0 | V1 | V2 | V3 | V4 | V5
deriving stock (Eq, Ord, Bounded, Enum, Show, Generic)
deriving (FromJSON, ToJSON) via (Schema Version)
deriving (Arbitrary) via (GenericUniform Version)
@@ -85,12 +91,10 @@ versionInt V1 = 1
versionInt V2 = 2
versionInt V3 = 3
versionInt V4 = 4
+versionInt V5 = 5
supportedVersions :: [Version]
-supportedVersions = [minBound .. V4]
-
-developmentVersions :: [Version]
-developmentVersions = [V4]
+supportedVersions = [minBound .. maxBound]
----------------------------------------------------------------------
@@ -179,7 +183,84 @@ type VersionAPI =
:> Get '[JSON] VersionInfo
)
-versionSwagger :: S.Swagger
-versionSwagger = toSwagger (Proxy @VersionAPI)
+data VersionAPITag
+
+-- Development versions
$(genSingletons [''Version])
+
+isDevelopmentVersion :: Version -> Bool
+isDevelopmentVersion V0 = False
+isDevelopmentVersion V1 = False
+isDevelopmentVersion V2 = False
+isDevelopmentVersion V3 = False
+isDevelopmentVersion _ = True
+
+developmentVersions :: [Version]
+developmentVersions = filter isDevelopmentVersion supportedVersions
+
+-- Version-aware swagger generation
+
+$(promoteOrdInstances [''Version])
+
+type family SpecialiseToVersion (v :: Version) api
+
+type instance
+ SpecialiseToVersion v (From w :> api) =
+ If (v < w) EmptyAPI (SpecialiseToVersion v api)
+
+type instance
+ SpecialiseToVersion v (Until w :> api) =
+ If (v < w) (SpecialiseToVersion v api) EmptyAPI
+
+type instance
+ SpecialiseToVersion v ((s :: Symbol) :> api) =
+ s :> SpecialiseToVersion v api
+
+type instance
+ SpecialiseToVersion v (Named n api) =
+ Named n (SpecialiseToVersion v api)
+
+type instance
+ SpecialiseToVersion v (Capture' mod sym a :> api) =
+ Capture' mod sym a :> SpecialiseToVersion v api
+
+type instance
+ SpecialiseToVersion v (Summary s :> api) =
+ Summary s :> SpecialiseToVersion v api
+
+type instance
+ SpecialiseToVersion v (Verb m s t r) =
+ Verb m s t r
+
+type instance
+ SpecialiseToVersion v (MultiVerb m t r x) =
+ MultiVerb m t r x
+
+type instance SpecialiseToVersion v RawM = RawM
+
+type instance
+ SpecialiseToVersion v (ReqBody t x :> api) =
+ ReqBody t x :> SpecialiseToVersion v api
+
+type instance
+ SpecialiseToVersion v (QueryParam' mods l x :> api) =
+ QueryParam' mods l x :> SpecialiseToVersion v api
+
+type instance
+ SpecialiseToVersion v (Header' opts l x :> api) =
+ Header' opts l x :> SpecialiseToVersion v api
+
+type instance
+ SpecialiseToVersion v (Description desc :> api) =
+ Description desc :> SpecialiseToVersion v api
+
+type instance
+ SpecialiseToVersion v (StreamBody' opts f t x :> api) =
+ StreamBody' opts f t x :> SpecialiseToVersion v api
+
+type instance SpecialiseToVersion v EmptyAPI = EmptyAPI
+
+type instance
+ SpecialiseToVersion v (api1 :<|> api2) =
+ SpecialiseToVersion v api1 :<|> SpecialiseToVersion v api2
diff --git a/libs/wire-api/src/Wire/API/Routes/Versioned.hs b/libs/wire-api/src/Wire/API/Routes/Versioned.hs
index be309b77fd..1ca7bac058 100644
--- a/libs/wire-api/src/Wire/API/Routes/Versioned.hs
+++ b/libs/wire-api/src/Wire/API/Routes/Versioned.hs
@@ -57,6 +57,10 @@ instance
route _p ctx d = route (Proxy :: Proxy (ReqBody cts (Versioned v a) :> api)) ctx (fmap (. unVersioned) d)
+type instance
+ SpecialiseToVersion w (VersionedReqBody v cts a :> api) =
+ VersionedReqBody v cts a :> SpecialiseToVersion w api
+
instance
( S.ToSchema (Versioned v a),
HasSwagger api,
diff --git a/libs/wire-api/src/Wire/API/Routes/WebSocket.hs b/libs/wire-api/src/Wire/API/Routes/WebSocket.hs
index 756605366a..72354d95bc 100644
--- a/libs/wire-api/src/Wire/API/Routes/WebSocket.hs
+++ b/libs/wire-api/src/Wire/API/Routes/WebSocket.hs
@@ -31,6 +31,7 @@ import Servant.Server.Internal.Delayed
import Servant.Server.Internal.RouteResult
import Servant.Server.Internal.Router
import Servant.Swagger
+import Wire.API.Routes.Version
-- | A websocket that relates to a 'PendingConnection'
-- Copied and adapted from:
@@ -62,6 +63,8 @@ instance HasServer WebSocketPending ctx where
errHeaders = mempty
}
+type instance SpecialiseToVersion v WebSocketPending = WebSocketPending
+
instance HasSwagger WebSocketPending where
toSwagger _ =
mempty
diff --git a/libs/wire-api/src/Wire/API/VersionInfo.hs b/libs/wire-api/src/Wire/API/VersionInfo.hs
index 0fa210b01e..1d05a55e02 100644
--- a/libs/wire-api/src/Wire/API/VersionInfo.hs
+++ b/libs/wire-api/src/Wire/API/VersionInfo.hs
@@ -42,7 +42,6 @@ import Servant
import Servant.Client.Core
import Servant.Server.Internal.Delayed
import Servant.Server.Internal.DelayedIO
-import Servant.Swagger
import Wire.API.Routes.ClientAlgebra
vinfoObjectSchema :: ValueSchema NamedSwaggerDoc v -> ObjectSchema SwaggerDoc [v]
@@ -108,9 +107,6 @@ instance
clientWithRoute pm (Proxy @api) req
hoistClientMonad pm _ f = hoistClientMonad pm (Proxy @api) f
-instance HasSwagger (Until v :> api) where
- toSwagger _ = mempty
-
instance RoutesToPaths api => RoutesToPaths (Until v :> api) where
getRoutes = getRoutes @api
@@ -159,8 +155,5 @@ instance
clientWithRoute pm (Proxy @api) req
hoistClientMonad pm _ f = hoistClientMonad pm (Proxy @api) f
-instance HasSwagger api => HasSwagger (From v :> api) where
- toSwagger _ = toSwagger (Proxy @api)
-
instance RoutesToPaths api => RoutesToPaths (From v :> api) where
getRoutes = getRoutes @api
diff --git a/services/brig/src/Brig/API/Public.hs b/services/brig/src/Brig/API/Public.hs
index 188db1b0ff..b27c409444 100644
--- a/services/brig/src/Brig/API/Public.hs
+++ b/services/brig/src/Brig/API/Public.hs
@@ -113,6 +113,7 @@ import Wire.API.Error.Brig qualified as E
import Wire.API.Federation.API
import Wire.API.Federation.Error
import Wire.API.Properties qualified as Public
+import Wire.API.Routes.API
import Wire.API.Routes.Internal.Brig qualified as BrigInternalAPI
import Wire.API.Routes.Internal.Cannon qualified as CannonInternalAPI
import Wire.API.Routes.Internal.Cargohold qualified as CargoholdInternalAPI
@@ -121,13 +122,13 @@ import Wire.API.Routes.Internal.Spar qualified as SparInternalAPI
import Wire.API.Routes.MultiTablePaging qualified as Public
import Wire.API.Routes.Named (Named (Named))
import Wire.API.Routes.Public.Brig
-import Wire.API.Routes.Public.Brig.OAuth qualified as OAuth
-import Wire.API.Routes.Public.Cannon qualified as CannonAPI
-import Wire.API.Routes.Public.Cargohold qualified as CargoholdAPI
-import Wire.API.Routes.Public.Galley qualified as GalleyAPI
-import Wire.API.Routes.Public.Gundeck qualified as GundeckAPI
-import Wire.API.Routes.Public.Proxy qualified as ProxyAPI
-import Wire.API.Routes.Public.Spar qualified as SparAPI
+import Wire.API.Routes.Public.Brig.OAuth
+import Wire.API.Routes.Public.Cannon
+import Wire.API.Routes.Public.Cargohold
+import Wire.API.Routes.Public.Galley
+import Wire.API.Routes.Public.Gundeck
+import Wire.API.Routes.Public.Proxy
+import Wire.API.Routes.Public.Spar
import Wire.API.Routes.Public.Util qualified as Public
import Wire.API.Routes.Version
import Wire.API.SwaggerHelper (cleanupSwagger)
@@ -166,17 +167,32 @@ docsAPI =
--
-- Dual to `internalEndpointsSwaggerDocsAPI`.
versionedSwaggerDocsAPI :: Servant.Server VersionedSwaggerDocsAPI
+versionedSwaggerDocsAPI (Just (VersionNumber V5)) =
+ swaggerSchemaUIServer $
+ ( serviceSwagger @VersionAPITag @'V5
+ <> serviceSwagger @BrigAPITag @'V5
+ <> serviceSwagger @GalleyAPITag @'V5
+ <> serviceSwagger @SparAPITag @'V5
+ <> serviceSwagger @CargoholdAPITag @'V5
+ <> serviceSwagger @CannonAPITag @'V5
+ <> serviceSwagger @GundeckAPITag @'V5
+ <> serviceSwagger @ProxyAPITag @'V5
+ <> serviceSwagger @OAuthAPITag @'V5
+ )
+ & S.info . S.title .~ "Wire-Server API"
+ & S.info . S.description ?~ $(embedText =<< makeRelativeToProject "docs/swagger.md")
+ & cleanupSwagger
versionedSwaggerDocsAPI (Just (VersionNumber V4)) =
swaggerSchemaUIServer $
- ( brigSwagger
- <> versionSwagger
- <> GalleyAPI.swaggerDoc
- <> SparAPI.swaggerDoc
- <> CargoholdAPI.swaggerDoc
- <> CannonAPI.swaggerDoc
- <> GundeckAPI.swaggerDoc
- <> ProxyAPI.swaggerDoc
- <> OAuth.swaggerDoc
+ ( serviceSwagger @VersionAPITag @'V4
+ <> serviceSwagger @BrigAPITag @'V4
+ <> serviceSwagger @GalleyAPITag @'V4
+ <> serviceSwagger @SparAPITag @'V4
+ <> serviceSwagger @CargoholdAPITag @'V4
+ <> serviceSwagger @CannonAPITag @'V4
+ <> serviceSwagger @GundeckAPITag @'V4
+ <> serviceSwagger @ProxyAPITag @'V4
+ <> serviceSwagger @OAuthAPITag @'V4
)
& S.info . S.title .~ "Wire-Server API"
& S.info . S.description ?~ $(embedText =<< makeRelativeToProject "docs/swagger.md")
@@ -218,6 +234,11 @@ internalEndpointsSwaggerDocsAPI ::
PortNumber ->
S.Swagger ->
Servant.Server (VersionedSwaggerDocsAPIBase service)
+internalEndpointsSwaggerDocsAPI service examplePort swagger (Just (VersionNumber V5)) =
+ swaggerSchemaUIServer $
+ swagger
+ & adjustSwaggerForInternalEndpoint service examplePort
+ & cleanupSwagger
internalEndpointsSwaggerDocsAPI service examplePort swagger (Just (VersionNumber V4)) =
swaggerSchemaUIServer $
swagger
diff --git a/services/brig/test/integration/API/Swagger.hs b/services/brig/test/integration/API/Swagger.hs
index 2d2525dcdc..ec5ec230e9 100644
--- a/services/brig/test/integration/API/Swagger.hs
+++ b/services/brig/test/integration/API/Swagger.hs
@@ -48,7 +48,7 @@ tests p _opts brigNoImplicitVersion =
[ test p "toc" $ do
forM_ ["/api/swagger-ui", "/api/swagger-ui/index.html", "/api/swagger.json"] $ \pth -> do
r <- get (brigNoImplicitVersion . path pth . expect2xx)
- liftIO $ assertEqual "toc is intact" (responseBody r) (Just "please pick an api version
/v0/api/swagger-ui/
/v1/api/swagger-ui/
/v2/api/swagger-ui/
/v3/api/swagger-ui/
/v4/api/swagger-ui/
")
+ liftIO $ assertEqual "toc is intact" (Just "please pick an api version
/v0/api/swagger-ui/
/v1/api/swagger-ui/
/v2/api/swagger-ui/
/v3/api/swagger-ui/
/v4/api/swagger-ui/
/v5/api/swagger-ui/
") (responseBody r)
-- are all versions listed?
forM_ [minBound :: Version ..] $ \v -> liftIO $ assertBool (show v) ((cs (toQueryParam v) :: String) `isInfixOf` (cs . fromJust . responseBody $ r))
-- FUTUREWORK: maybe test that no invalid versions are listed? (that wouldn't
diff --git a/services/cannon/src/Cannon/API/Public.hs b/services/cannon/src/Cannon/API/Public.hs
index 0eb81bf5fb..4a559f9f17 100644
--- a/services/cannon/src/Cannon/API/Public.hs
+++ b/services/cannon/src/Cannon/API/Public.hs
@@ -31,7 +31,7 @@ import Servant
import Wire.API.Routes.Named
import Wire.API.Routes.Public.Cannon
-publicAPIServer :: ServerT PublicAPI Cannon
+publicAPIServer :: ServerT CannonAPI Cannon
publicAPIServer = Named @"await-notifications" streamData
streamData :: UserId -> ConnId -> Maybe ClientId -> PendingConnection -> Cannon ()
diff --git a/services/cannon/src/Cannon/Run.hs b/services/cannon/src/Cannon/Run.hs
index df5f6e06a6..b0657c59f8 100644
--- a/services/cannon/src/Cannon/Run.hs
+++ b/services/cannon/src/Cannon/Run.hs
@@ -58,7 +58,7 @@ import Wire.API.Routes.Internal.Cannon qualified as Internal
import Wire.API.Routes.Public.Cannon
import Wire.API.Routes.Version.Wai
-type CombinedAPI = PublicAPI :<|> Internal.API
+type CombinedAPI = CannonAPI :<|> Internal.API
run :: Opts -> IO ()
run o = do
@@ -88,7 +88,7 @@ run o = do
app = middleware (serve (Proxy @CombinedAPI) server)
server :: Servant.Server CombinedAPI
server =
- hoistServer (Proxy @PublicAPI) (runCannonToServant e) publicAPIServer
+ hoistServer (Proxy @CannonAPI) (runCannonToServant e) publicAPIServer
:<|> hoistServer (Proxy @Internal.API) (runCannonToServant e) internalServer
tid <- myThreadId
E.handle uncaughtExceptionHandler $ do
diff --git a/services/cargohold/src/CargoHold/API/Public.hs b/services/cargohold/src/CargoHold/API/Public.hs
index 280e00b02b..a896025bdc 100644
--- a/services/cargohold/src/CargoHold/API/Public.hs
+++ b/services/cargohold/src/CargoHold/API/Public.hs
@@ -41,7 +41,7 @@ import Wire.API.Routes.AssetBody
import Wire.API.Routes.Internal.Cargohold
import Wire.API.Routes.Public.Cargohold
-servantSitemap :: ServerT ServantAPI Handler
+servantSitemap :: ServerT CargoholdAPI Handler
servantSitemap =
renewTokenV3
:<|> deleteTokenV3
diff --git a/services/cargohold/src/CargoHold/Run.hs b/services/cargohold/src/CargoHold/Run.hs
index 556cabf367..ae43e1e96a 100644
--- a/services/cargohold/src/CargoHold/Run.hs
+++ b/services/cargohold/src/CargoHold/Run.hs
@@ -55,7 +55,7 @@ import Wire.API.Routes.Internal.Cargohold
import Wire.API.Routes.Public.Cargohold
import Wire.API.Routes.Version.Wai
-type CombinedAPI = FederationAPI :<|> ServantAPI :<|> InternalAPI
+type CombinedAPI = FederationAPI :<|> CargoholdAPI :<|> InternalAPI
run :: Opts -> IO ()
run o = lowerCodensity $ do
@@ -89,7 +89,7 @@ mkApp o = Codensity $ \k ->
(Proxy @CombinedAPI)
((o ^. settings . federationDomain) :. Servant.EmptyContext)
( hoistServerWithDomain @FederationAPI (toServantHandler e) federationSitemap
- :<|> hoistServerWithDomain @ServantAPI (toServantHandler e) servantSitemap
+ :<|> hoistServerWithDomain @CargoholdAPI (toServantHandler e) servantSitemap
:<|> hoistServerWithDomain @InternalAPI (toServantHandler e) internalSitemap
)
r
diff --git a/services/galley/src/Galley/API/Public/Servant.hs b/services/galley/src/Galley/API/Public/Servant.hs
index 86e223c522..ea777ec499 100644
--- a/services/galley/src/Galley/API/Public/Servant.hs
+++ b/services/galley/src/Galley/API/Public/Servant.hs
@@ -32,7 +32,7 @@ import Galley.App
import Wire.API.Routes.API
import Wire.API.Routes.Public.Galley
-servantSitemap :: API ServantAPI GalleyEffects
+servantSitemap :: API GalleyAPI GalleyEffects
servantSitemap =
conversationAPI
<@> teamConversationAPI
diff --git a/services/galley/src/Galley/Run.hs b/services/galley/src/Galley/Run.hs
index bd2ad81994..60924f451f 100644
--- a/services/galley/src/Galley/Run.hs
+++ b/services/galley/src/Galley/Run.hs
@@ -63,7 +63,7 @@ import System.Logger qualified as Log
import System.Logger.Extended (mkLogger)
import Util.Options
import Wire.API.Routes.API
-import Wire.API.Routes.Public.Galley qualified as GalleyAPI
+import Wire.API.Routes.Public.Galley
import Wire.API.Routes.Version.Wai
run :: Opts -> IO ()
@@ -151,7 +151,7 @@ bodyParserErrorFormatter' _ _ errMsg =
}
type CombinedAPI =
- GalleyAPI.ServantAPI
+ GalleyAPI
:<|> InternalAPI
:<|> FederationAPI
:<|> Servant.Raw
diff --git a/services/spar/src/Spar/API.hs b/services/spar/src/Spar/API.hs
index 5c27ad4407..4107e44910 100644
--- a/services/spar/src/Spar/API.hs
+++ b/services/spar/src/Spar/API.hs
@@ -32,7 +32,7 @@ module Spar.API
api,
-- * API types
- API,
+ SparAPI,
-- ** Individual API pieces
APIAuthReqPrecheck,
@@ -113,7 +113,7 @@ import qualified Wire.Sem.Random as Random
app :: Env -> Application
app ctx =
SAML.setHttpCachePolicy $
- serve (Proxy @API) (hoistServer (Proxy @API) (runSparToHandler ctx) (api $ sparCtxOpts ctx) :: Server API)
+ serve (Proxy @SparAPI) (hoistServer (Proxy @SparAPI) (runSparToHandler ctx) (api $ sparCtxOpts ctx) :: Server SparAPI)
api ::
( Member GalleyAccess r,
@@ -144,7 +144,7 @@ api ::
Member (Logger (Msg -> Msg)) r
) =>
Opts ->
- ServerT API (Sem r)
+ ServerT SparAPI (Sem r)
api opts =
apiSSO opts
:<|> apiIDP
diff --git a/services/spar/src/Spar/Run.hs b/services/spar/src/Spar/Run.hs
index 58681ad897..5331fddabc 100644
--- a/services/spar/src/Spar/Run.hs
+++ b/services/spar/src/Spar/Run.hs
@@ -44,7 +44,7 @@ import qualified Network.Wai.Handler.Warp as Warp
import Network.Wai.Utilities.Request (lookupRequestId)
import qualified Network.Wai.Utilities.Server as WU
import qualified SAML2.WebSSO as SAML
-import Spar.API (API, app)
+import Spar.API (SparAPI, app)
import Spar.App
import qualified Spar.Data as Data
import Spar.Data.Instances ()
@@ -116,7 +116,7 @@ mkApp sparCtxOpts = do
let wrappedApp =
versionMiddleware (fold (disabledAPIVersions sparCtxOpts))
. WU.heavyDebugLogging heavyLogOnly logLevel sparCtxLogger
- . servantPrometheusMiddleware (Proxy @API)
+ . servantPrometheusMiddleware (Proxy @SparAPI)
. WU.catchErrors sparCtxLogger []
-- Error 'Response's are usually not thrown as exceptions, but logged in
-- 'renderSparErrorWithLogging' before the 'Application' can construct a 'Response'
diff --git a/services/spar/test/Test/Spar/APISpec.hs b/services/spar/test/Test/Spar/APISpec.hs
index ceefb59e48..07bfdb8fde 100644
--- a/services/spar/test/Test/Spar/APISpec.hs
+++ b/services/spar/test/Test/Spar/APISpec.hs
@@ -37,9 +37,9 @@ import Wire.API.User.Saml (SsoSettings)
spec :: Spec
spec = do
-- Note: SCIM types are not validated because their content-type is 'SCIM'.
- validateEveryToJSON (Proxy @API.API)
+ validateEveryToJSON (Proxy @API.SparAPI)
it "api consistency" $ do
- pathsConsistencyCheck (routesToPaths @API.API) `shouldBe` mempty
+ pathsConsistencyCheck (routesToPaths @API.SparAPI) `shouldBe` mempty
it "roundtrip: IdPMetadataInfo" . property $ \(val :: IdPMetadataInfo) -> do
let withoutRaw (IdPMetadataValue _ x) = x
(withoutRaw <$> (Aeson.eitherDecode . Aeson.encode) val) `shouldBe` Right (withoutRaw val)
diff --git a/tools/fedcalls/src/Main.hs b/tools/fedcalls/src/Main.hs
index 79ac0e7887..c1b4471da9 100644
--- a/tools/fedcalls/src/Main.hs
+++ b/tools/fedcalls/src/Main.hs
@@ -42,17 +42,16 @@ import Data.Swagger
)
import Imports
import Language.Dot as D
+import Wire.API.Routes.API
import Wire.API.Routes.Internal.Brig qualified as BrigIRoutes
-import Wire.API.Routes.Public.Brig qualified as BrigRoutes
-import Wire.API.Routes.Public.Cannon qualified as CannonRoutes
-import Wire.API.Routes.Public.Cargohold qualified as CargoholdRoutes
-import Wire.API.Routes.Public.Galley qualified as GalleyRoutes
-import Wire.API.Routes.Public.Gundeck qualified as GundeckRoutes
-import Wire.API.Routes.Public.Proxy qualified as ProxyRoutes
--- import qualified Wire.API.Routes.Internal.Cannon as CannonIRoutes
--- import qualified Wire.API.Routes.Internal.Cargohold as CargoholdIRoutes
--- import qualified Wire.API.Routes.Internal.LegalHold as LegalHoldIRoutes
-import Wire.API.Routes.Public.Spar qualified as SparRoutes
+import Wire.API.Routes.Public.Brig
+import Wire.API.Routes.Public.Cannon
+import Wire.API.Routes.Public.Cargohold
+import Wire.API.Routes.Public.Galley
+import Wire.API.Routes.Public.Gundeck
+import Wire.API.Routes.Public.Proxy
+import Wire.API.Routes.Public.Spar
+import Wire.API.Routes.Version
------------------------------
@@ -72,13 +71,13 @@ swaggers =
-- services, use that in /services/brig/src/Brig/API/Public.hs instead of
-- doing it by hand.
- BrigRoutes.brigSwagger, -- TODO: s/brigSwagger/swaggerDoc/ like everybody else!
- CannonRoutes.swaggerDoc,
- CargoholdRoutes.swaggerDoc,
- GalleyRoutes.swaggerDoc,
- GundeckRoutes.swaggerDoc,
- ProxyRoutes.swaggerDoc,
- SparRoutes.swaggerDoc,
+ serviceSwagger @BrigAPITag @'V5,
+ serviceSwagger @CannonAPITag @'V5,
+ serviceSwagger @CargoholdAPITag @'V5,
+ serviceSwagger @GalleyAPITag @'V5,
+ serviceSwagger @GundeckAPITag @'V5,
+ serviceSwagger @ProxyAPITag @'V5,
+ serviceSwagger @SparAPITag @'V5,
-- TODO: collect all internal apis somewhere else (brig?), and expose them
-- via an internal swagger api end-point.