Skip to content

Commit 015072e

Browse files
committed
update workflow to test haskell servant ping
1 parent 067442f commit 015072e

File tree

11 files changed

+488
-0
lines changed

11 files changed

+488
-0
lines changed

.github/workflows/samples-haskell.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ on:
55
paths:
66
- samples/server/petstore/haskell-yesod/**
77
- samples/server/petstore/haskell-servant/**
8+
- samples/server/others/haskell-servant-ping/**
89
- samples/client/petstore/haskell-http-client/**
910
pull_request:
1011
paths:
1112
- samples/server/petstore/haskell-yesod/**
1213
- samples/server/petstore/haskell-servant/**
14+
- samples/server/others/haskell-servant-ping/**
1315
- samples/client/petstore/haskell-http-client/**
1416
jobs:
1517
build:
@@ -22,6 +24,7 @@ jobs:
2224
# servers
2325
- samples/server/petstore/haskell-yesod/
2426
- samples/server/petstore/haskell-servant/
27+
- samples/server/others/haskell-servant-ping/
2528
- samples/client/petstore/haskell-http-client/
2629
steps:
2730
- uses: actions/checkout@v4

bin/configs/haskell-servant-ping.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
generatorName: haskell
2+
outputDir: samples/server/others/haskell-servant-ping
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/ping.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/haskell-servant
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.openapi-generator-ignore
2+
README.md
3+
Setup.hs
4+
lib/PingTest/API.hs
5+
lib/PingTest/Types.hs
6+
ping-test.cabal
7+
stack.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.8.0-SNAPSHOT
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Auto-Generated OpenAPI Bindings to `PingTest`
2+
3+
The library in `lib` provides auto-generated-from-OpenAPI bindings to the PingTest API.
4+
5+
## Installation
6+
7+
Installation follows the standard approach to installing Stack-based projects.
8+
9+
1. Install the [Haskell `stack` tool](http://docs.haskellstack.org/en/stable/README).
10+
2. Run `stack install` to install this package.
11+
12+
Otherwise, if you already have a Stack project, you can include this package under the `packages` key in your `stack.yaml`:
13+
```yaml
14+
packages:
15+
- location:
16+
git: https://github.com/yourGitOrg/yourGitRepo
17+
commit: somecommit
18+
```
19+
20+
## Main Interface
21+
22+
The main interface to this library is in the `PingTest.API` module, which exports the PingTestBackend type. The PingTestBackend
23+
type can be used to create and define servers and clients for the API.
24+
25+
## Creating a Client
26+
27+
A client can be created via the `createPingTestClient` function, which will generate a function for every endpoint of the API.
28+
Then these functions can be invoked with `runPingTestClientWithManager` or more conveniently with `callPingTestClient`
29+
(depending if you want an `Either` back or you want to catch) to access the API endpoint they refer to, if the API is served
30+
at the `url` you specified.
31+
32+
For example, if `localhost:8080` is serving the PingTest API, you can write:
33+
34+
```haskell
35+
{-# LANGUAGE RecordWildCards #-}
36+
37+
import PingTest.API as API
38+
39+
import Network.HTTP.Client (newManager)
40+
import Network.HTTP.Client.TLS (tlsManagerSettings)
41+
import Servant.Client (ClientEnv, mkClientEnv, parseBaseUrl)
42+
43+
44+
main :: IO ()
45+
main = do
46+
-- Configure the BaseUrl for the client
47+
url <- parseBaseUrl "http://localhost:8080/"
48+
49+
-- You probably want to reuse the Manager across calls, for performance reasons
50+
manager <- newManager tlsManagerSettings
51+
52+
-- Create the client (all endpoint functions will be available)
53+
let PingTestBackend{..} = API.createPingTestClient
54+
55+
-- Any PingTest API call can go here, e.g. here we call `getSomeEndpoint`
56+
API.callPingTest (mkClientEnv manager url) getSomeEndpoint
57+
```
58+
59+
## Creating a Server
60+
61+
In order to create a server, you must use the `runPingTestMiddlewareServer` function. However, you unlike the client, in which case you *got* a `PingTestBackend`
62+
from the library, you must instead *provide* a `PingTestBackend`. For example, if you have defined handler functions for all the
63+
functions in `PingTest.Handlers`, you can write:
64+
65+
```haskell
66+
{-# LANGUAGE RecordWildCards #-}
67+
68+
import PingTest.API
69+
-- required dependency: wai
70+
import Network.Wai (Middleware)
71+
-- required dependency: wai-extra
72+
import Network.Wai.Middleware.RequestLogger (logStdout)
73+
74+
-- A module you wrote yourself, containing all handlers needed for the PingTestBackend type.
75+
import PingTest.Handlers
76+
77+
-- If you would like to not use any middlewares you could use runPingTestServer instead
78+
79+
-- Combined middlewares
80+
requestMiddlewares :: Middleware
81+
requestMiddlewares = logStdout
82+
83+
-- Run a PingTest server on localhost:8080
84+
main :: IO ()
85+
main = do
86+
let server = PingTestBackend{..}
87+
config = Config "http://localhost:8080/"
88+
runPingTestMiddlewareServer config requestMiddlewares server
89+
```
90+
91+
## Authentication
92+
93+
Currently basic, bearer and API key authentication is supported. The API key must be provided
94+
in the request header.
95+
96+
For clients authentication the function `clientAuth` is generated automatically. For basic
97+
authentication the argument is of type `BasicAuthData` provided by `Servant.API.BasicAuth`.
98+
For bearer and API key authentication the argument is the key/token and is of type `Text`.
99+
Protected endpoints on the client will receive an extra argument. The value returned by
100+
`clientAuth keyTokenOrBasic` can then be used to make authenticated requests.
101+
102+
For the server you are free to choose a custom data type. After you specified an instance of
103+
`AuthServerData` it is automatically added as a first argument to protected endpoints:
104+
105+
```
106+
newtype Account = Account {unAccount :: Text}
107+
type instance AuthServerData Protected = Account
108+
```
109+
110+
Additionally, you have to provide value for the `PingTestAuth` type provided by the
111+
`PingTest.API` module:
112+
113+
```
114+
auth :: PingTestAuth
115+
auth =
116+
PingTestAuth
117+
{ lookupUser = lookupAccount,
118+
authError = \request -> err401 {errBody = "Missing header"}
119+
}
120+
```
121+
122+
`lookupAccount` is a user defined function used to verify the key, token or basic auth data.
123+
`authError` takes a `Request` and returns a `ServerError`. The value is used by the server
124+
functions:
125+
126+
```
127+
runPingTestMiddlewareServer config requestMiddlewares auth server
128+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

0 commit comments

Comments
 (0)