2016-11-17 3 views
2

最近、要求されたルートが既存のAPIエンドポイントや別の静的資産と一致しない場合は、バックエンドからファイル(たとえば、index.html)を返す必要はありません。これは、react-routerbrowserHistoryを使用すると特に便利です。キャッチオールまたはデフォルトルーティング

私はServantでこれにどのようにアプローチするのか少し困惑しています。

data Wombat = Wombat 
    { id :: Int 
    , name :: String 
    } deriving (Eq, Show, Generic) 
instance ToJSON Wombat 

wombatStore :: [Wombat] 
wombatStore = 
    [ Wombat 0 "Gertrude" 
    , Wombat 1 "Horace" 
    , Wombat 2 "Maisie" 
    , Wombat 3 "Julius" 
    ] 

wombats :: Handler [Wombat] 
wombats = return wombatStore 

wombat :: Int -> Handler Wombat 
wombat wid = do 
    case find (\w -> Main.id w == wid) wombatStore of 
    Just x -> return x 
    Nothing -> throwE err404 

type API = 
    "api" :> "wombats" :> Get '[JSON] [Wombat] :<|> 
    "api" :> "wombats" :> Capture "id" Int :> Get '[JSON] Wombat :<|> 
    Raw 

api :: Proxy API 
api = Proxy 

server :: Server API 
server = wombats 
    :<|> wombat 
    :<|> serveDirectory "static" 

app :: Application 
app = serve api server 

main :: IO() 
main = run 3000 app 

私がしたい:404年代をインターセプトすると、移動するための方法かもしれないが、その後の進路時々APIは、合法的に404を発行する必要がありますここで私は実験に使用してきたもののようなものだ場合、私は不思議をしましたリクエストがAPIエンドポイントや静的ディレクトリ内のものと一致しない場合、HTML応答を送信する「デフォルトルート」を追加する方法についての例を見るのが大好きです。トイレポhere

答えて

2

あなたは基本的にそれを持っています。 serveDirectory "static"は、例えばので、我々が持っている可能性があり、任意のWAI Applicationによって置き換えることができますので、

Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived 

... 
{-# LANGUAGE OverloadedStrings #-} 
... 
import Network.Wai  (responseLBS) 
import Network.HTTP.Types (status200) 
... 
server :: Server API 
server = wombats 
    :<|> wombat 
    :<|> hello 

hello :: Application 
hello req respond = respond $ 
    responseLBS 
    status200      -- 
    [("Content-Type", "text/plain")] -- headers 
    "Hello, World!"     -- content 
... 

を第一近似として、充実した話をthe docsアプリケーションは単にRequest -> ResponseあるWAIが、 IOにアクセスできるので、ファイルが存在するかどうかを確認し、存在する場合はそれをチェックし、そうでない場合は好きなことを行うことができます。実際、waiはtype Middleware = Application -> Applicationを定義しているので、hello(または他のアプリケーション!)をファイル存在チェッカー・アンド・サーバにまとめた便利なミドルウェアを考えるかもしれません。ここで

+0

ありがとうございました。本当に助かりました! –

2

は別のルートである:

serveDirectory

serveDirectory = staticApp . defaultFileServerSettings . addTrailingPathSeparator 

defaultFileServerSettingsとして定義されますが、ファイルが見つからなかった場合、あなたが望むものを提供するために変更することができますフィールドssLookupFileが含まれています。おそらく:

import WaiAppStatic.Types 
import WaiAppStatic.Storage.Filesystem 
import Network.Wai.Application.Static 
import System.FilePath 

fileOrIndex root pieces = do 
    res <- ssLookupFile (defaultFileServerSettings root) pieces 
    case res of 
    LRNotFound -> undefined -- index.html here 
    _ -> return res 

serveStatic root = 
    let root' = addTrailingPathSeparator root in 
    staticApp $ (defaultFileServerSettings root') {ssLookupFile = fileOrIndex root'} 
+0

別の良いオプション!これを説明していただきありがとうございます。 –

関連する問題