您当前的位置:首页 > 电脑百科 > 站长技术 > 网站

快速用 Haskell 构建超级简单的 Web 技术栈

时间:2019-11-29 11:28:18  来源:  作者:

如何用标准化的,通用的纯函数编程语言Haskell来构建Web?Haskell构建的Web拥有着什么样的优点呢?让我们来看看构建的过程吧。

快速用 Haskell 构建超级简单的 Web 技术栈

作者%20|%20William%20Yao

译者%20|弯月,责编%20|%20maozz

出品%20|%20CSDN(ID:CSDNnews)

以下为译文:

Haskell有大量的库可用于满足基本的后台需求,从日志输出到数据库访问,再到Web服务器的定义和路由,应有尽有。

拥有选择的自由固然很好,但如果你刚刚接触这个领域,那么大量的选择可能会让你目不暇接。也许你没法自信地判断出这些选择之间的区别。例如,你需要查询数据库。

那么,你需要Squeal提供的列名强保证,以及深度SQL嵌入功能吗?还是青睐Opaleye在保证类型安全的前提下的简单性?或者只是使用简单的postgresql-simple就好?还是使用Selda?或者……

我用最简单的库写了一个Web应用程序,一方面是想告诉你,你不需要担心技术栈是否足够先进,另一方面也是我自己的学习过程。

如果你不知道怎样用Haskell构建真正的应用程序,为什么不去学习呢?我会尽可能保持代码的简单性。

点击此处可查看源代码(https://gitlab.com/williamyaoh/haskell-web-stack)。

下面我们来看一看我选择的这些库,以及它们的功能,还有这个应用程序的功能。

1.这个Web应用程序究竟是什么呢?

它是一个网站,用户可以在这个网站上创建定时器和做笔记。

我举个例子说明该网站的用途:某人想设置多个定时器来跟踪多个反应物的过程,同时用笔记来记录他们需要关心的事情、下次制作配方时需要改进的事情,等等。

再举一个例子,某个人在玩MOBA游戏,比如英雄联盟或者刀塔2,他们可以在另一台显示器上打开一个页面来跟踪关键技能的冷却时间,同时用笔记记录宏操作、对手的组合,以及团战时需要关注技的冷却等。

在这个应用程序中我将演示:

  • 会话,用户可以刷新页面,或者关闭页面后再打开,但在打开之后应该看到相同的内容。

  • 持久化和数据库访问,我们需要将每个用户的定时器和笔记保存下来。另一个需求是定时器需要维持剩余的时间(用户设置了一个30分钟的定时器,然后不小心关闭了页面,应该如何?)

  • 运行时的配置,因为我们不能把数据库连接的信息硬编码到代码里。

  • 日志。日志对于Web应用的作用不言而喻。

2.我用到了哪些库?

路由和Web服务器:Spock

最终我选择了Spock,因为它易于使用。如果你用过Ruby的Sinatra,那么Spock应该不会陌生。Spock也自带了会话管理,这一点非常好。

例如,定义一个拥有几条路由的服务器,返回html和JSON,代码大致如下:


 

{-# LANGUAGE OverloadedStrings #-}

import Web.Spock as Spock

import Web.Spock.Config as Spock

import Data.Aeson as A

main :: IO

main = do

spockCfg <- defaultSpockCfg PCNoDatabase

runSpock 3000 $ spock spockCfg $ do

get root $ do

Spock.html "<div>Hello world!</div>"

get "users" $ do

Spock.json (A.object [ "users" .= users ])

get ("users" <//> var <//> "friends") $ \userID -> do

Spock.json (A.object [ "userID" .= (userID :: Int), "friends" .= A. ])

where users :: [String]

users = ["bob", "alice"]

数据库访问:postgresql-simple

postgresql-simple基本上只允许您对数据库运行原始SQL查询,而没有多余的装饰,例如防止注入攻击。它可以实现您的期望,仅此而已。

{-# LANGUAGE OverloadedStrings #-}

import Database.PostgreSQL.Simple

userLoginsQuery :: Query

userLoginsQuery =

"SELECT l.user_id, COUNT(1) FROM logins l GROUP BY l.user_id;"

getUserLogins :: Connection -> IO [(Int, Int)]

getUserLogins conn = query_ conn userLoginsQuery

数据库访问:postgresql-simple

postgresql-simple可以让你在数据库上运行原始的SQL查询,它只提供最基本的额外处理,比如防止注入攻击等。它仅完成你需要的东西,没有任何额外的功能。


 

{-# LANGUAGE OverloadedStrings #-}

import Database.PostgreSQL.Simple

userLoginsQuery :: Query

userLoginsQuery =

"SELECT l.user_id, COUNT(1) FROM logins l GROUP BY l.user_id;"

getUserLogins :: Connection -> IO [(Int, Int)]

getUserLogins conn = query_ conn userLoginsQuery

配置:configurator

configurator能够从文件中读取配置,并解析成Haskell数据类型。与普通的配置文件读取器相比它的功能要多一些。

如果你习惯了直接读取配置文件,那么configurator还有一些额外功能。例如,配置项可以嵌套分组,configurator还提供了热重载来监视配置文件变化。


 

# An example config file.

App_name = "The Whispering Fog"

db {

pool {

stripes = 4

resource_ttl = 300

}

username = "pallas"

password = "thefalloflatinium"

dbname = "italy"

}


 

{-# LANGUAGE OverloadedStrings #-}

import Data.Configurator as Cfg

import Database.PostgreSQL.Simple

data MyAppConfig = MyAppConfig

{ appName :: String

, appDBConnection :: Connection

}

getAppConfig :: IO MyAppConfig

getAppConfig = do

cfgFile <- Cfg.load ["app-configuration.cfg"]

name <- Cfg.require cfgFile "app_name"

conn <- do

username <- Cfg.require cfgFile "db.username"

password <- Cfg.require cfgFile "db.password"

dbname <- Cfg.require cfgFile "db.dbname"

connect $ defaultConnectInfo

{ connectUser = username

, connectPassword = password

, connectDatabase = dbname

}

pure $ MyAppConfig

{ appName = name

, appDBConnection = conn

}

日志:fast-logger

fast-logger提供了一个相对简单易用的日志解决方案。在Web应用程序的示例中,我只输出到了stderr,但它还可以支持输出日志到文件。虽然它支持许多类型,但绝大多数情况下,你需要定义一个辅助函数,接收一个LoggerSet,以及需要记录的信息。


 

import System.Log.FastLogger as Log

logMsg :: Log.LoggerSet -> String -> IO

logMsg logSet msg =

Log.pushLogStrLn logSet (Log.toLogStr msg)

doSomething :: IO

doSomething = do

logSet <- Log.newStderrLoggerSet Log.defaultBufSize

logMsg logSet "message 1"

logMsg logSet "message 2"

HTML生成:blaze-html

尽管本项目的后台并不需要生成太多HTML,但值得一提的是,blaze-html正是我需要的。

基本上它就是将HTML浅层嵌入到了Haskell DSL中。如果你会编写HTML,那你就会使用这个库。


 

{-# LANGUAGE OverloadedStrings #-}

import Data.ByteString.Lazy

import Text.Blaze.Html5 as HTML

import Text.Blaze.Html5.Attributes as HTML hiding ( title )

import Text.Blaze.Html.Renderer.Utf8 as HTML

dashboardHTML :: HTML.Html

dashboardHTML = HTML.html $

HTML.docTypeHtml $ do

HTML.head $ do

HTML.title "Timers and Notes"

HTML.meta ! HTML.charset "utf-8"

HTML.script ! HTML.src "/js/bundle.js" $ ""

HTML.body $ do

HTML.div ! HTML.id "content" $ ""

dashboardBytes :: ByteString

dashboardBytes = HTML.renderHtml dashboardHTML

构建前端:make + npm

没错,它们并不是库。但我们依然需要某种JAVAScript前端,因为定时器需要实时更新。Webpack能够生成JS包,而Make能够组装最终的应用程序。

这些东西无需我多说,网上有很多相关的资源。

3.我必须要用这些库吗?

当然不是。如果你第一次接触Haskell,那么有这些疑问是很自然的。不要让这篇文章限制了你的思路。尽管这个应用程序可以运行,但许多部分用于生产环境下的Haskell时并不理想。

例如,许多Haskell程序员很可能会使用Servant而不是Spock来定义API端点。如果你想了解其他库,那当然应该跟随你的直觉。

你可以把这些库和这个应用程序作为起点。我建议你用这些代码作为学习的机会,理解它的原理,然后自己试着修改。Haskell很好的一点就是它非常易于重构或者升级,而不会破坏已有的功能。

一旦掌握了这个应用程序,就可以用更高级的库来替换它们,来获得更多的保证。同时,这也是一个增量学习的过程。

将数据库访问的库从postgresql-simple升级到支持类型安全的库。我推荐Opaleye!

将API定义的库从Spock升级到Servant

利用QuickCheck或hedgehog增加自动测试。例如,你可以测试服务器的每个错误响应都返回了JSON格式的错误信息。

你还可以尝试替换前端和构建系统。

升级前端,使用PureScript或Elm来替换原始的JavaScript

升级构建系统,利用Shake替换make构建更健壮的系统

原文:https://williamyaoh.com/posts/2019-11-16-a-dead-simple-web-stack.html

本文为 CSDN 翻译,转载请注明来源出处。

【End】



Tags:Haskell   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
如何用标准化的,通用的纯函数编程语言Haskell来构建Web?Haskell构建的Web拥有着什么样的优点呢?让我们来看看构建的过程吧。作者 | William Yao译者 |弯月,责编 | maozz出品 | C...【详细内容】
2019-11-29  Tags: Haskell  点击:(81)  评论:(0)  加入收藏
▌简易百科推荐
今天我们来聊一下北京地区的《ICP经营许可证》有多好办,现在的互联网上提供的商机越来越多,增值电信业务十分火爆,企业通过互联网突破地域的限制,把公司产品卖到更远的地方,同时...【详细内容】
2021-12-17  梦想理应飞翔Yy    Tags:《ICP经营许可证》   点击:(12)  评论:(0)  加入收藏
转自: https://blog.kermsite.com/p/blog-intro/由于格式问题,部分链接、表格可能会失效,若失效请访问原文此专题将详细介绍如何从零开始搭建一个个人博客。Dec 01, 2021阅读时...【详细内容】
2021-12-17  LaLiLi    Tags:个人博客   点击:(7)  评论:(0)  加入收藏
SP证是第二类增值电信业务经营许可证的简称。分为全网SP证和地网SP证。申请经营许可证是在工信部申请,全网SP经营许可证的有效期是5年,全网SP许可证在工信部办理全网SP续期,地...【详细内容】
2021-11-01  s陳述    Tags:sp证书   点击:(39)  评论:(0)  加入收藏
现在还有许多人不知道EDI许可证是什么东西今天我就来给大家讲解一下.EDI许可证就是一种增值电信业务经营许可证。是针对在线数据处理和交易处理业务需求的专业资格证书。 《...【详细内容】
2021-10-28  soberXx    Tags:edi许可证   点击:(75)  评论:(0)  加入收藏
元素的化学概念,如周期表中的化学元素,一切物质都是由元素构成的。对程序员而言,网站建设制作就是代码构成网站。企业网站设计者也收集了各种各样的元素,但并非所有元素都需要运...【详细内容】
2021-10-26  南宁云尚网络    Tags:企业网站   点击:(40)  评论:(0)  加入收藏
在运营网站的过程中,有一件不可忽略的事情。那就是网站上线之前需要完成 ICP 备案。说到这里,很多朋友就提出疑问了~&middot; 什么是 ICP 备案呢?&middot; ICP 备案需要哪些材...【详细内容】
2021-10-22  启测云    Tags:ICP备案   点击:(46)  评论:(0)  加入收藏
最近有朋友问我,我公司有外资就不能申请ICP许可证了么?外资的定义是什么?其实是可以的,但有一个特定条件必须满足,外资公司是指公司有外资股东,比如香港、加拿大、美国、韩国等等,...【详细内容】
2021-10-21  小白速看Z    Tags:ICP   点击:(51)  评论:(0)  加入收藏
自互联网出现以来,超文本传输协议http协议被广泛用于在Web浏览器和网站服务器之间传递信息,但随着互联网的发展,另一种协议&mdash;&mdash;https出现,并与http一同服务于这个互联...【详细内容】
2021-10-20  我是FEIYA    Tags:https   点击:(44)  评论:(0)  加入收藏
Grafana Loki 是一个日志聚合工具,它是功能齐全的日志堆栈的核心。图片来自 包图网先看看结果有多轻量吧: Loki 是一个为有效保存日志数据而优化的数据存储。日志数据的高效索...【详细内容】
2021-09-14    51CTO  Tags:Loki日志   点击:(97)  评论:(0)  加入收藏
背景最近做微信小程序开发比较多,大家知道线上微信小程序为了安全起见,要求后端通信协议必须是HTTPS,这就要求需要安装证书。为了测试预发布线上环境,特地买了个最便宜的域名,为...【详细内容】
2021-09-14  小李子说程序    Tags:HTTPS证书   点击:(125)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条