标签: scotty

Scotty:连接池作为monad阅读器

有数以万亿计的monad教程,包括读者,当你阅读它时似乎都很清楚.但是当你真正需要写作时,它就变成了另一回事.

我从未使用过读者,只是在实践中从未使用过.所以尽管我读到了它,但我不知道如何去做.

我需要在Scotty中实现一个简单的数据库连接池,以便每个操作都可以使用该池.该池必须是"全局的",并且可由所有操作功能访问.我读到了这样做的方法是Reader monad.如果还有其他方式,请告诉我.

你能帮我一下,并正确地说明如何用Reader做这个吗?如果我看到自己的例子如何完成,我可能会学得更快.

{-# LANGUAGE OverloadedStrings #-}

module DB where

import Data.Pool
import Database.MongoDB

-- Get data from config
ip = "127.0.0.1"
db = "index"

--Create the connection pool
pool :: IO (Pool Pipe)
pool = createPool (runIOE $ connect $ host ip) close 1 300 5

-- Run a database action with connection pool
run :: Action IO a -> IO (Either Failure a)
run act = flip withResource (\x -> access x master db act) =<< …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-wai scotty

19
推荐指数
1
解决办法
1865
查看次数

通用函数何时不通用?

我正在使用scotty和处理Haskell服务器persistent.许多处理程序需要访问数据库连接池,所以我采取了以这种方式在整个应用程序中传递池:

main = do
    runNoLoggingT $ withSqlitePool ":memory:" 10 $ \pool ->
        liftIO $ scotty 7000 (app pool)

app pool = do
    get "/people" $ do
        people <- liftIO $ runSqlPool getPeople pool
        renderPeople people
    get "/foods" $ do
        food <- liftIO $ runSqlPool getFoods pool
        renderFoods food
Run Code Online (Sandbox Code Playgroud)

其中,getPeoplegetFoods适合persistent返回数据库操作[Person][Food]分别.

调用liftIOrunSqlPool在池上的模式在一段时间后变得令人厌倦 - 如果我可以将它们重构为单个函数(如Yesod的那样runDB,它只会接受查询并返回适当的类型),那不是很好.我写这样的东西的尝试是:

runDB' :: (MonadIO m) => ConnectionPool -> SqlPersistT …
Run Code Online (Sandbox Code Playgroud)

polymorphism haskell scotty

16
推荐指数
3
解决办法
950
查看次数

使用Scotty的网络I/O的吞吐量意外低

我试图对Scotty进行测试,以测试网络I/O效率和整体吞吐量.

为此,我设置了两个用Haskell编写的本地服务器.一个不做任何事情而只是充当API的人.

代码相同

{-# LANGUAGE OverloadedStrings #-}


import Web.Scotty

import Network.Wai.Middleware.RequestLogger 

import Control.Monad
import Data.Text
import Control.Monad.Trans
import Data.ByteString
import Network.HTTP.Types (status302)
import Data.Time.Clock
import Data.Text.Lazy.Encoding (decodeUtf8)
import Control.Concurrent
import Network.HTTP.Conduit
import Network.Connection (TLSSettings (..))
import Network.HTTP.Client
import Network
main = do 
  scotty 4001 $ do
    middleware logStdoutDev
    get "/dummy_api" $ do
        text $ "dummy response"
Run Code Online (Sandbox Code Playgroud)

我写了另一个调用此服务器并返回响应的服务器.

{-# LANGUAGE OverloadedStrings #-}


import Web.Scotty

import Network.Wai.Middleware.RequestLogger 

import Control.Monad
import Control.Monad.Trans
import qualified Data.Text.Internal.Lazy as LT
import Data.ByteString
import Network.HTTP.Types (status302)
import …
Run Code Online (Sandbox Code Playgroud)

benchmarking haskell http-conduit scotty

16
推荐指数
1
解决办法
334
查看次数

关于scotty Haskell Web框架的简单问题

考虑最简单的scotty应用程序:

{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty

import Data.Monoid (mconcat)

main = scotty 3000 $ do
    get "/:word" $ do
        beam <- param "word"
        html $ mconcat ["<h1>Scotty, ", beam, " me up!</h1>"]
Run Code Online (Sandbox Code Playgroud)

我将此代码放入app.hs并使用GHC进行编译.我用它来运行它./app.简单.

  1. 当人们访问该网站时会发生什么?它只是一个./app正在运行的.每当每个用户触发get "/:word" $ do一行时,是否在同一个应用程序中创建了新的线程?有多少这样的线程可以存在?千?万?

  2. 运行./app后显示消息Setting phasers to stun... (port 3000) (ctrl-c to quit).但它没有显示更多.它不会输出传入的Web请求.我该怎么做呢?这对于记录目的很有用.

haskell haskell-wai haskell-warp scotty

10
推荐指数
2
解决办法
1604
查看次数

Haskell Persistent:如果我有整数变量的密钥,如何通过密钥从db获取实体?

我使用Persistent orm和scotty web框架.

我希望通过id从db获取值.这些ID来自GET请求

有"获取"功能,它接受"密钥实体"变量并返回"可能实体".

我使用以下代码从db获取值

k <- keyFromValues $ [(PersistInt64 myOwnIntVarFromRequest)]
case k of
    Left _ -> {-some processing-}
    Right x -> do
    t <- liftIO . runDb $ get (x::Key Post) --Post is one of my models
    case t of
        Nothing -> {-processing-}
        Just x -> {-processing-}
Run Code Online (Sandbox Code Playgroud)

这些代码非常丑陋.但我不知道如何做得更好

所以我的问题是如何在不调用keyFromValues的情况下获取"Key Entity"类型的变量.

PS抱歉我的英语不好

haskell persistent yesod scotty

10
推荐指数
1
解决办法
1606
查看次数

将每个monad变换器作为MonadTrans的实例是否真的是一种默认做法?

所以真实世界Haskell说:

每个monad变换器都是MonadTrans的一个实例

但我玩斯科蒂,并发现它的基础单子转换ScottyT没有的一个实例MonadTrans.

看一下发行说明,这似乎是一个刻意的设计决定:这里.引用:

ScottyT的monad参数已经解耦,导致ScottyT构造函数的类型发生变化.因此,ScottyT不再是MonadTrans实例......

我希望你理解我的困惑.不过,我会尝试制定严格的问题:

  • 为什么不想让monad变换器成为一个实例MonadTrans呢?
  • 您如何解释上述ScottyT设计的变化?

PS:我明白我可以定义一个MonadTrans ScottyT自己的实例,但是我应该吗?(回到问题链接)

monads haskell monad-transformers scotty

9
推荐指数
1
解决办法
184
查看次数

在Web.Scotty中使用StateT

我正在尝试制作一个存储数据的愚蠢的网络服务器State.我正在使用Web.Scotty.我之前使用过ReaderT和scotty来访问配置,但是遵循相同的方法在这里不起作用.它会根据每个请求重置状态.

我想在程序启动时设置初始状态,然后在程序的整个生命周期中保持相同的状态.

我怎样才能做到这一点?(以下为每个请求创建一个新状态)

{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty.Trans
import Control.Monad.State (StateT, evalStateT, lift)
import qualified Control.Monad.State as S
import Data.Text.Lazy (Text)

main :: IO ()
main = do
  let runner = flip evalStateT "message"
  scottyT 3000 runner runner routes

routes :: ScottyT Text (StateT Text IO) ()
routes = do

  get "/data" $ do
    val <- lift S.get
    text val

  put "/data/:val" $ do
    val <- param "val"
    lift $ S.put val
    text …
Run Code Online (Sandbox Code Playgroud)

monads haskell monad-transformers scotty

8
推荐指数
1
解决办法
626
查看次数

用户在Scotty注册

在学习Haskell的同时,我在Scotty框架中创建了一个小型Web应用程序.接下来我想添加用户注册.

注册应支持电子邮件/密码和Google/FaceBook登录选项.如果用户在"现场"注册,他也应该能够使用G/FB帐户登录,反之亦然.

是否有一些标准/简单的方法来实现Scotty

我真的不喜欢自己进行注册和身份验证,但我想只是关于如何实现标准电子邮件/密码reg/auth的一些指示会很有帮助.

authentication haskell registration scotty

7
推荐指数
0
解决办法
292
查看次数

如何将Reader monad添加到Scotty的monad?

我正在尝试使用Scotty来构建一个非常简单的API.我想扩展Scotty monad,以便我的路由处理程序操作能够访问一个不变的环境.我相信这样做的方法是Reader在堆栈中添加一个monad.现在我只想传递一些Text数据.

我把Scotty monads扩展如下:

type BrandyScottyM = ScottyT TL.Text (ReaderT T.Text IO)
type BrandyActionM = ActionT TL.Text (ReaderT T.Text IO)
Run Code Online (Sandbox Code Playgroud)

https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Core.hs

所以我的第一个问题是,这是正确的方法吗?

我已经成功地改变了我的路由处理程序的类型,但我无法弄清楚如何使用这个堆栈启动Scotty.我尝试过以下方法:

runScotty :: Port -> Text -> BrandyScottyM () -> IO ()
runScotty port file = T.scottyT port ((\f -> runReader f file)) id
Run Code Online (Sandbox Code Playgroud)

https://github.com/stu-smith/Brandy/blob/0838a63537d7e396ac82d58d460c6529349303d3/src/Main.hs

但我得到错误:

  Couldn't match type `IO' with `Data.Functor.Identity.Identity'
    Expected type: Reader Text (IO a)
      Actual type: ReaderT Text IO a
    In the first argument of `runReader', namely `f'
    In the …
Run Code Online (Sandbox Code Playgroud)

haskell monad-transformers scotty

6
推荐指数
1
解决办法
735
查看次数

Haskell Monads 和 liftIO 我不明白

您好社区,感谢您的宝贵时间。

\n

我有一个错误,我不确定错误是什么,但我认为问题是:\n没有从ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO)到 的IO 转换器Web.Scotty.Internal.Types.ScottyT

\n

但我想知道为什么编译器与ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO). 这就是为什么我只使用 String 并删除了所有出现的{-# LANGUAGE OverloadedStrings #-}但仍然收到错误。另一方面,这应该是IO [String],不是吗?\n正如你所提到的,我真的不知道是什么ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO)

\n

在另一个地方,我已经liftIO成功使用了一个a -> IO String函数。我想我也以同样的方式使用它们。

\n

我想我慢慢地感觉到了 monad 是什么,但不太确定。我真的不知道为什么我必须使用一个lift函数。

\n

错误信息:

\n
    \xe2\x80\xa2 No instance for (MonadIO\n                         (Web.Scotty.Internal.Types.ScottyT\n                            text-1.2.4.1:Data.Text.Internal.Lazy.Text IO))\n        arising from a use of \xe2\x80\x98liftIO\xe2\x80\x99\n    \xe2\x80\xa2 In a stmt of a \'do\' block:\n        paths <- liftIO $ getAllFilePaths2 path\n      In the expression:\n        do …
Run Code Online (Sandbox Code Playgroud)

monads haskell lifting io-monad scotty

5
推荐指数
1
解决办法
470
查看次数