scotty 系列教程之 echo server

本章为 scotty 系列教程的第二篇,读者可先阅读 第一篇 学习如何使用 stack 构建一个 Haskell 的项目。

本章的目标是使用 scotty 构建一个 echo server,用 curl 测试如下:

$ curl http://127.0.0.1:3000/?echo=abc
abc
$ curl http://127.0.0.1:3000/ -d echo=cdf
cdf

我们继续使用 上篇 所建立的 helloworld 为基础建立 echo server

修改 src/Lib.hs 如下:

{-# LANGUAGE OverloadedStrings #-}

module Lib
    ( someFunc
    ) where

import           Web.Scotty

someFunc :: IO ()
someFunc =  scotty 3000 $ do
  get "/" $ do
    echo <- param "echo"
    text echo

  post "/" $ do
    echo <- param "echo"
    text echo

这里用了 getpost 的方法,然后通过 param 获取 echo 的信息然后输出。

编译一下:

$ stack build --system-ghc 
Warning: File listed in helloworld.cabal file does not exist: README.md
helloworld-0.1.0.0: build (lib + exe)
Preprocessing library helloworld-0.1.0.0...
[1 of 1] Compiling Lib              ( src/Lib.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Lib.o )

/Users/lmj/repo/dispatch/helloworld/src/Lib.hs:7:1: error:
    Failed to load interface for ‘Web.Scotty’
    Use -v to see a list of the files searched for.
Warning: File listed in helloworld.cabal file does not exist: README.md

--  While building package helloworld-0.1.0.0 using:
      /Users/lmj/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 --builddir=.stack-work/dist/x86_64-osx/Cabal-1.24.2.0 build lib:helloworld exe:helloworld-exe --ghc-options " -ddump-hi -ddump-to-file"
    Process exited with code: ExitFailure 1

编译器抱怨没有找到 Web.Scotty,这是缺少依赖 scotty 导致的。
打开 helloworld.cabal, 将 scotty 添加到 librarybuild-depends, 如下:

library
  hs-source-dirs:      src
  exposed-modules:     Lib
  build-depends:       base >= 4.7 && < 5
                     , scotty
  default-language:    Haskell2010

重新编译一下:

$ stack build --system-ghc 
Warning: File listed in helloworld.cabal file does not exist: README.md
fail-4.9.0.0: using precompiled package
nats-1.1.1: using precompiled package
regex-base-0.93.2: using precompiled package
regex-posix-0.95.2: using precompiled package
regex-compat-0.95.1: using precompiled package
scotty-0.11.0: using precompiled package
helloworld-0.1.0.0: configure (lib + exe)
Configuring helloworld-0.1.0.0...
helloworld-0.1.0.0: build (lib + exe)
Preprocessing library helloworld-0.1.0.0...
[1 of 1] Compiling Lib              ( src/Lib.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/Lib.o )
Preprocessing executable 'helloworld-exe' for helloworld-0.1.0.0...
[1 of 1] Compiling Main             ( app/Main.hs, .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/helloworld-exe/helloworld-exe-tmp/Main.o ) [Lib changed]
Linking .stack-work/dist/x86_64-osx/Cabal-1.24.2.0/build/helloworld-exe/helloworld-exe ...
Warning: File listed in helloworld.cabal file does not exist: README.md
helloworld-0.1.0.0: copy/register
Installing library in
/Users/lmj/repo/dispatch/helloworld/.stack-work/install/x86_64-osx/lts-8.5/8.0.2/lib/x86_64-osx-ghc-8.0.2/helloworld-0.1.0.0-1f3dj2GjzoiFgLQm1bUvr4
Installing executable(s) in
/Users/lmj/repo/dispatch/helloworld/.stack-work/install/x86_64-osx/lts-8.5/8.0.2/bin
Registering helloworld-0.1.0.0...
Completed 7 action(s).

接下来运行测试一下:

$ stack exec --system-ghc helloworld-exe
Setting phasers to stun... (port 3000) (ctrl-c to quit)

打开另外一个终端测试:

$ curl http://127.0.0.1:3000/?echo=abc
abc 
$ curl http://127.0.0.1:3000/ -d echo=cdf
cdf

到这里整个 echo server 基本完成。

继续看 src/Lib.hs 的代码,getpost 的处理代码是一样的,我们是否写成一个函数呢? 答案是可以的。

阅读文档发现 getpost 定义如下:

get :: RoutePattern -> ActionM () -> ScottyM ()
post :: RoutePattern -> ActionM () -> ScottyM ()

所以可以定义一个 echoHandler 如下:

echoHandler :: ActionM ()
echoHandler = do
  echo <- param "echo"
  text echo

修改 src/Lib.hs 如下:

{-# LANGUAGE OverloadedStrings #-}

module Lib
    ( someFunc
    ) where

import           Web.Scotty

someFunc :: IO ()
someFunc =  scotty 3000 $ do
  get  "/" echoHandler
  post "/" echoHandler

echoHandler :: ActionM ()
echoHandler = do
  echo <- param "echo"
  text echo

编译测试如上,由读者自行完成。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,398评论 25 707
  • 关于JavaScript继承这一块,其实困扰了我很久,更多的是强行记忆,没有真正的理解,我看了很多书籍,博客关于J...
    moonburn阅读 444评论 0 8
  • 1 上学≠学习最近与身边的人聊天,发现许多工作中的人都是不读书的,下班的业余时间都是在追剧,或者干别的事情,我对此...
    致远007阅读 640评论 0 0
  • 是夜 明明四周安静得一塌糊涂,我却只觉得吵 像是有千百只蚊虫在耳边嗡嗡嚷嚷地乱叫 我似乎觉着有些耳鸣眼花 原谅我竟...
    若许宁阅读 211评论 0 0