5

私は単純なハローワールドサーバントアプリケーションを持っています。静的または動的な HTML ページをいくつか追加する必要があります。どうやってやるの?ドキュメントには記載されていません。Haskell コードで html レイアウトを作成したくないことに注意してください。すでに作成されている html ページを Haskell に表示させたいのです。

アップデート:

これをどのように組み合わせることができますか:

type MyApi = "/" :> Raw

server :: Server MyApi
server = serveDirectory "static/" -- index.html, about.html 

私がすでに持っているもので:

  type API = 
    "api" :> "items" :> Get '[JSON] [MyData] :<|>
    "api" :> "items" :> Capture "id" Int :> Get '[JSON] MyData


  app :: Application
  app = serve api server

  api :: Proxy API
  api = Proxy

  server :: Server API
  server = getItems :<|> getItem

  startApp :: IO ()
  startApp =  run 1234 app

更新 2:

働く:

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

動作していません、まったく応答がありません:

type API = 
    "api" :> "items" :> Get '[JSON] [MyData] :<|>
    "api" :> "items" :> Capture "id" Int :> Get '[JSON] MyData :<|>
    "/" :> Raw

-- or

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

なぜだろう?

4

1 に答える 1

7

REST API と静的 html ページを組み合わせるには?

によって、静的 Web サイトを含むディレクトリをルート パスに提供できますserveDirectory。サーバント API の最後のケースである必要があります。そうしないと、他のケースが一致しなくなります。

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

api :: Proxy API 
api = Proxy

server :: Server API 
server = getItems
    :<|> getItem 
    :<|> serveDirectory "static/"

また、静的ページ名が API でクラッシュした場合、それはシャドウされます。


なぜではないの"/" :> Rawですか?

ブラウザがいくつかの静的ページをキャッシュしているようです。キャッシュを消去した後"/" :> Raw、応答がありません。/index.html

APIの文字列リテラルは、最初に正当なURI部分にエンコードされるため"/""%2F"ファイルがマップされます/%2F/index.html


ルートケースをどのように処理できるか知っていますか?

ルート パスで応答を提供するには、Getプレフィックスなしでエンドポイントを定義できます。

type API = Get '[HTML] RawHtml

最後の行を除いて、API のどこにでも配置できます。

ローカル ファイルを html 応答として提供するには、ファイルを他のバイト文字列と区別する必要があります。おそらく newtype でラップします。

newtype RawHtml = RawHtml { unRaw :: BS.ByteString }

-- tell Servant how to render the newtype to html page, in this case simply unwrap it
instance MimeRender HTML RawHtml where
    mimeRender _ =  unRaw

そしてあなたのコントローラーで:

-- ...
:<|> fmap RawHtml (liftIO $ BS.readFile "your/file/path.html")

または、ページに既に別のアドレスがある場合は、ユーザーをそこにリダイレクトできます。

-- ...
:<|> throwError err301 { errHeaders = [("Location", "index.html")] }

すでに index.html を返しています。うーん、なぜ正確に index.html なのですか?

serveDirectorystaticApp設定で wai アプリケーションを呼び出しますdefaultFileServerSettings。その設定では、ユーザーはリダイレクトされるindex.htmindex.html、何か問題が発生した場合:

defaultFileServerSettings root = StaticSettings
    { ssLookupFile = fileSystemLookup (fmap Just . hashFile) root
    , ssMkRedirect = defaultMkRedirect
    , ssGetMimeType = return . defaultMimeLookup . fromPiece . fileName
    , ssMaxAge = NoMaxAge
    , ssListing = Just defaultListing
    , ssIndices = map unsafeToPiece ["index.html", "index.htm"]
    , ssRedirectToIndex = False
    , ssUseHash = False
    , ssAddTrailingSlash = False
    , ss404Handler = Nothing
    }
于 2016-04-02T12:42:55.520 に答える