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

Added OperationId combinator #1378

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 15 additions & 7 deletions servant-client-core/src/Servant/Client/Core/HasClient.hs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ import Servant.API
FromSourceIO (..), Header', Headers (..), HttpVersion,
IsSecure, MimeRender (mimeRender),
MimeUnrender (mimeUnrender), NoContent (NoContent),
NoContentVerb, QueryFlag, QueryParam', QueryParams, Raw,
ReflectMethod (..), RemoteHost, ReqBody', SBoolI, Stream,
StreamBody', Summary, ToHttpApiData, ToSourceIO (..), Vault,
Verb, WithNamedContext, contentType, getHeadersHList,
getResponse, toQueryParam, toUrlPiece)
NoContentVerb, OperationId, QueryFlag, QueryParam',
QueryParams, Raw, ReflectMethod (..), RemoteHost, ReqBody',
SBoolI, Stream, StreamBody', Summary, ToHttpApiData,
ToSourceIO (..), Vault, Verb, WithNamedContext, contentType,
getHeadersHList, getResponse, toQueryParam, toUrlPiece)
import Servant.API.ContentTypes
(contentTypes, AllMime (allMime), AllMimeUnrender (allMimeUnrender))
import Servant.API.TypeLevel (FragmentUnique, AtLeastOneFragment)
Expand Down Expand Up @@ -496,6 +496,14 @@ instance HasClient m api => HasClient m (Description desc :> api) where

hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl

-- | Ignore @'OperationId'@ in client functions.
instance HasClient m api => HasClient m (OperationId opid :> api) where
type Client m (OperationId opid :> api) = Client m api

clientWithRoute pm _ = clientWithRoute pm (Proxy :: Proxy api)

hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl

-- | If you use a 'QueryParam' in one of your endpoints in your API,
-- the corresponding querying function will automatically take
-- an additional argument of the type specified by your 'QueryParam',
Expand Down Expand Up @@ -753,7 +761,7 @@ instance ( HasClient m api

-- | Ignore @'Fragment'@ in client functions.
-- See <https://ietf.org/rfc/rfc2616.html#section-15.1.3> for more details.
--
--
-- Example:
--
-- > type MyApi = "books" :> Fragment Text :> Get '[JSON] [Book]
Expand All @@ -774,7 +782,7 @@ instance ( HasClient m api

type Client m (Fragment a :> api) = Client m api

clientWithRoute pm _ = clientWithRoute pm (Proxy :: Proxy api)
clientWithRoute pm _ = clientWithRoute pm (Proxy :: Proxy api)

hoistClientMonad pm _ = hoistClientMonad pm (Proxy :: Proxy api)

Expand Down
21 changes: 21 additions & 0 deletions servant-docs/golden/comprehensive.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,27 @@

## GET /named-context

### Response:

- Status code 200
- Headers: []

- Supported content types are:

- `application/json;charset=utf-8`
- `application/json`

- Example (`application/json;charset=utf-8`, `application/json`):

```javascript

```

## GET /operation-id

### getFoo


### Response:

- Status code 200
Expand Down
10 changes: 10 additions & 0 deletions servant-docs/src/Servant/Docs/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,16 @@ instance (KnownSymbol desc, HasDocs api)
action' = over notes (|> note) action
note = DocNote (symbolVal (Proxy :: Proxy desc)) []

instance (KnownSymbol opid, HasDocs api)
=> HasDocs (OperationId opid :> api) where

docsFor Proxy (endpoint, action) =
docsFor subApiP (endpoint, action')

where subApiP = Proxy :: Proxy api
action' = over notes (|> note) action
note = DocNote (symbolVal (Proxy :: Proxy opid)) []

instance (KnownSymbol desc, HasDocs api)
=> HasDocs (Summary desc :> api) where

Expand Down
7 changes: 7 additions & 0 deletions servant-foreign/src/Servant/Foreign/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,13 @@ instance HasForeign lang ftype api
foreignFor lang ftype Proxy req =
foreignFor lang ftype (Proxy :: Proxy api) req

instance HasForeign lang ftype api
=> HasForeign lang ftype (OperationId opid :> api) where
type Foreign ftype (OperationId opid :> api) = Foreign ftype api

foreignFor lang ftype Proxy req =
foreignFor lang ftype (Proxy :: Proxy api) req

-- | Utility class used by 'listFromAPI' which computes
-- the data needed to generate a function for each endpoint
-- and hands it all back in a list.
Expand Down
15 changes: 11 additions & 4 deletions servant-server/src/Servant/Server/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ import Servant.API
CaptureAll, Description, EmptyAPI, Fragment,
FramingRender (..), FramingUnrender (..), FromSourceIO (..),
Header', If, IsSecure (..), NoContentVerb, QueryFlag,
QueryParam', QueryParams, Raw, ReflectMethod (reflectMethod),
RemoteHost, ReqBody', SBool (..), SBoolI (..), SourceIO,
Stream, StreamBody', Summary, ToSourceIO (..), Vault, Verb,
WithNamedContext)
OperationId, QueryParam', QueryParams, Raw,
ReflectMethod (reflectMethod), RemoteHost, ReqBody',
SBool (..), SBoolI (..), SourceIO, Stream, StreamBody',
Summary, ToSourceIO (..), Vault, Verb, WithNamedContext)
import Servant.API.ContentTypes
(AcceptHeader (..), AllCTRender (..), AllCTUnrender (..),
AllMime, MimeRender (..), MimeUnrender (..), NoContent,
Expand Down Expand Up @@ -745,6 +745,13 @@ instance HasServer api ctx => HasServer (Description desc :> api) ctx where
route _ = route (Proxy :: Proxy api)
hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt s

-- Ignore @'OperationId'@ in server handlers
instance HasServer api ctx => HasServer (OperationId opid :> api) ctx where
type ServerT (OperationId opid :> api) m = ServerT api m

route _ = route (Proxy :: Proxy api)
hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt s

-- | Singleton type representing a server that serves an empty API.
data EmptyServer = EmptyServer deriving (Typeable, Eq, Show, Bounded, Enum)

Expand Down
2 changes: 1 addition & 1 deletion servant/src/Servant/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ import Servant.API.ContentTypes
MimeUnrender (..), NoContent (NoContent), OctetStream,
PlainText)
import Servant.API.Description
(Description, Summary)
(Description, OperationId, Summary)
import Servant.API.Empty
(EmptyAPI (..))
import Servant.API.Experimental.Auth
Expand Down
8 changes: 8 additions & 0 deletions servant/src/Servant/API/Description.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
module Servant.API.Description (
-- * Combinators
Description,
OperationId,
Summary,
-- * Used as modifiers
FoldDescription,
Expand Down Expand Up @@ -46,6 +47,13 @@ data Summary (sym :: Symbol)
data Description (sym :: Symbol)
deriving (Typeable)

-- | Add a unique identifier for an endpoint
--
-- Example:
--
-- >>> type MyApi = OperationId "getBooksByISBN" :> "books" :> Capture "isbn" Text :> Get '[JSON] Book
data OperationId (sym :: Symbol)

-- | Fold list of modifiers to extract description as a type-level String.
--
-- >>> :kind! FoldDescription '[]
Expand Down
6 changes: 5 additions & 1 deletion servant/src/Servant/Links.hs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ import Servant.API.BasicAuth
import Servant.API.Capture
(Capture', CaptureAll)
import Servant.API.Description
(Description, Summary)
(Description, OperationId, Summary)
import Servant.API.Empty
(EmptyAPI (..))
import Servant.API.Experimental.Auth
Expand Down Expand Up @@ -532,6 +532,10 @@ instance HasLink sub => HasLink (Description s :> sub) where
type MkLink (Description s :> sub) a = MkLink sub a
toLink = simpleToLink (Proxy :: Proxy sub)

instance HasLink sub => HasLink (OperationId opid :> sub) where
type MkLink (OperationId opid :> sub) a = MkLink sub a
toLink = simpleToLink (Proxy :: Proxy sub)

instance HasLink sub => HasLink (Summary s :> sub) where
type MkLink (Summary s :> sub) a = MkLink sub a
toLink = simpleToLink (Proxy :: Proxy sub)
Expand Down
1 change: 1 addition & 0 deletions servant/src/Servant/Test/ComprehensiveAPI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type ComprehensiveAPIWithoutStreamingOrRaw' endpoint =
:<|> "capture-all" :> CaptureAll "foo" Int :> GET
:<|> "summary" :> Summary "foo" :> GET
:<|> "description" :> Description "foo" :> GET
:<|> "operation-id" :> OperationId "getFoo" :> GET
:<|> "alternative" :> ("left" :> GET :<|> "right" :> GET)
:<|> "fragment" :> Fragment Int :> GET
:<|> endpoint
Expand Down