-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathMain.hs
79 lines (73 loc) · 2.4 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | This module is a public API implementation
module Main where
import Control.Arrow hiding (app)
import Control.Exception (catch)
import Control.Lens
import Data.Maybe (fromMaybe)
import Data.Monoid
import Data.String.Class (fromStrictByteString, toString)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Network.HTTP.Client as HC
import Network.HTTP.Client
(HttpException(HttpExceptionRequest),
HttpExceptionContent(StatusCodeException))
import Network.HTTP.Types (status404, status500)
import Network.Wai
import Network.Wai.Handler.Warp hiding (Manager)
import qualified Network.Wreq as W
app :: HC.Manager -> Application
app mgr req respond =
case pathInfo req of
("api":"users":_) -> microservice "http://localhost:8082/"
("api":"albooms":_) -> microservice "http://localhost:8083/"
_ ->
respond
(responseLBS status404 [] ",,,(o,o),,,\n ';:`-':;' \n -\"-\"- \n")
where
microservice = microserviceProxy mgr req respond
getReqParams :: Request -> [(Text, Text)]
getReqParams req =
map
(fromStrictByteString *** fromStrictByteString . fromMaybe "")
(queryString req)
microserviceProxy ::
forall b.
HC.Manager
-> Request
-> (Network.Wai.Response -> IO b)
-> Text
-> IO b
microserviceProxy mgr req respond basePath = do
let opts =
W.defaults & W.manager .~ Right mgr & W.headers .~ requestHeaders req &
W.params .~
getReqParams req
url = basePath <> T.intercalate "/" (pathInfo req)
tryProxying opts url `catch` onErr
where
tryProxying opts url = do
r <-
case requestMethod req of
"GET" -> W.getWith opts (toString url)
"POST" -> requestBody req >>= W.postWith opts (toString url)
respond
(responseLBS
(r ^. W.responseStatus)
(r ^. W.responseHeaders)
(r ^. W.responseBody))
onErr :: HttpException -> IO b
onErr (HttpExceptionRequest req (StatusCodeException rsp _)) =
respond
(responseLBS (rsp ^. W.responseStatus) (rsp ^. W.responseHeaders) "")
onErr e = do
putStrLn ("Internal error: " ++ show e)
respond (responseLBS status500 [] "Internal server error")
main :: IO ()
main = do
mgr <- HC.newManager HC.defaultManagerSettings
run 8081 (app mgr)