原文来自静雅斋,转载请注明出处。

作为一门新兴的现代化语言,Swift 可以说是苹果在开发语言上的一次集大成之作,吸收了很多语言的优点。而且苹果还期望 Swift 能在服务端开发上能发挥作用。更加诱人的是,作为一种编译型语言,有着 C++ 一般的性能,并且相比 Golang、Java 来说使用 ARC 管理内存避免了 GC 导致进程停顿。可以说 Swift 就是程序员梦寐以求的语言。

Swift 目前在后端开发的缺点

虽然 Swift 本身有很多优点,但是在后端开发上依旧任重道远,比如有以下问题:

  1. 目前只适配了 Ubuntu 下的二进制包,没有 RHEL 等其他 Linux 下的二进制包

  2. 缺乏非 Mac 系统下的 IDE 开发,这个目前看起来好像只能指望 Jetbrains 了

  3. 没有其他语言那么完善的生态系统

  4. 缺乏的文档,比如包管理系统的语法文档,必须自行查看源代码

  5. 没有交叉编译链,不能在 Mac 上面编译出 Linux 可用的二进制文件

  6. 缺乏好用的单元测试

但是这些问题目前都有方法克服,比如使用 Docker 作为承载 Swift 程序的容器,而使用 Mac 来开发 Swift 程序也不是很大的问题,因为大多数的后端开发都是用 Mac 开发的。

Docker 的作用

笔者个人认为 Docker 解决的最大的问题就是开发环境和生产环境的矛盾,对于开发人员来说,追新永远是必备素质,而测试和运维不会希望环境变更导致的问题,比如线上服务器跑的是 CentOS,而 Swift 则是必须在 Ubuntu 上运行,但是 Docker 的出现就能解决这个问题。笔者认为最适合运行在 Docker 中的就是像 Web 这样的服务,Nginx 和数据库之类的就不适合放在 Docker 中,因为它们是有状态的,而且 Docker 这样的快速消亡快速创建的模式也不适合数据库这样对数据有着严格要求的应用。当然,Kubernetes 目前推出的 petset 就很适合数据库这样的有状态的应用。

Perfect 框架

Perfect 框架是 Swift 开发的 Web 应用服务器,它支持包括 Redis、SQLite、PostgreSQL、MySQL、MongoDB、FileMaker 这样的数据库,并且能以 fastcgi 或者 Web 服务器的形式提供服务。更加美妙的是,还有高质量的中文文档。

HelloWorld

Perfect 提供了基础模板工程,可以使用以下命令下载

> git clone git@github.com:PerfectlySoft/PerfectTemplate.git

然后安装依赖

> swift package fetch

然后就能编译运行了

# 以 Debug 方式编译
> swift build
# 以 Release 方式编译
> swift build -c release

分析 HelloWorld

HelloWorld 工程依赖了 Perfect-HTTPServer 模块,然后其中有两个源文件,arguments.swiftmain.swift
main.swift

import PerfectLib
import PerfectHTTP
import PerfectHTTPServer// Create HTTP server.
let server = HTTPServer()// Register your own routes and handlers
var routes = Routes()
routes.add(method: .get, uri: "/", handler: {request, response inresponse.setHeader(.contentType, value: "text/html")response.appendBody(string: "<html><title>Hello, world!</title><body>Hello, world!</body></html>")response.completed()}
)// Add the routes to the server.
server.addRoutes(routes)// Set a listen port of 8181
server.serverPort = 8181// Set a document root.
// This is optional. If you do not want to serve static content then do not set this.
// Setting the document root will automatically add a static file handler for the route /**
server.documentRoot = "./webroot"// Gather command line options and further configure the server.
// Run the server with --help to see the list of supported arguments.
// Command line arguments will supplant any of the values set above.
configureServer(server)do {// Launch the HTTP server.try server.start()
} catch PerfectError.networkError(let err, let msg) {print("Network error thrown: \(err) \(msg)")
}

用过 Node 的 express 框架的朋友是不是感觉很熟悉,使用事件循环处理 HTTP 请求,事实上早期的 Perfect 框架用的就是 libev 框架来处理事件循环的 HTTP 请求。
arguments.swift

import PerfectHTTPServer
import PerfectLib#if os(Linux)import SwiftGlibc
#elseimport Darwin
#endif// Check all command line arguments used to configure the server.
// These are all optional and you can remove or add arguments as required.
func configureServer(_ server: HTTPServer) {var sslCert: String?var sslKey: String?var args = CommandLine.argumentsfunc argFirst() -> String {guard let frst = args.first else {print("Argument requires value.")exit(-1)}return frst}let validArgs = ["--sslcert": {args.removeFirst()sslCert = argFirst()},"--sslkey": {args.removeFirst()sslKey = argFirst()},"--port": {args.removeFirst()server.serverPort = UInt16(argFirst()) ?? 8181},"--address": {args.removeFirst()server.serverAddress = argFirst()},"--root": {args.removeFirst()server.documentRoot = argFirst()},"--name": {args.removeFirst()server.serverName = argFirst()},"--runas": {args.removeFirst()server.runAsUser = argFirst()},"--help": {print("Usage: \(CommandLine.arguments.first!) [--port listen_port] [--address listen_address] [--name server_name] [--root root_path] [--sslcert cert_path --sslkey key_path] [--runas user_name]")exit(0)}]while args.count > 0 {if let closure = validArgs[args.first!.lowercased()] {closure()}args.removeFirst()}if sslCert != nil || sslKey != nil {if sslCert == nil || sslKey == nil {print("Error: if either --sslcert or --sslkey is provided then both --sslcert and --sslkey must be provided.")exit(-1)}if !File(sslCert!).exists || !File(sslKey!).exists {print("Error: --sslcert or --sslkey file did not exist.")exit(-1)}server.ssl = (sslCert: sslCert!, sslKey: sslKey!)}
}

这里就很简单了,就是提供参数用于 HTTP 服务器的创建,而这个好处就是能通过参数获得更多功能。

创建自己的工程

首先使用 swift package init 命令创建工程,一般来说如下

> swift package init --type executable

然后在 Package.swift 中增加依赖,但是 Swift 目前所有的 IDE 都没有提供对 PackageDescription 模块的代码提示,估计是因为这是 Swift 內建模块。具体内容得到 Swift 源代码中可以找到。
一般来说只要增加如下内容

import PackageDescriptionlet package = Package(name: "XXXX",dependencies: [.Package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", majorVersion: 2, minor: 0)]
)

然后创建 main.swift 文件,并且创建 HTTPServer 侦听端口,就能创建自己的工程了。

Docker

一般来说,Docker 目前想要运行 Swift 必须使用 Ubuntu 的镜像,因为 Swift 的预编译包只提供 Ubuntu 的压缩包,但是很多 Docker 镜像存在很多问题,比如缺少支持库,所以需要作出以下修改,下面提供一个样例

FROM swiftdocker/swift:3.0.1
MAINTAINER ChasonTang <chasontang@gmail.com>RUN apt-get update \&& apt-get install -y uuid-dev libcurl4-openssl-dev libssl-dev \ && git clone https://github.com/PerfectlySoft/PerfectTemplate /usr/src/PerfectTemplate \&& apt-get clean \&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
WORKDIR /usr/src/PerfectTemplate
RUN swift build -c release
CMD .build/release/PerfectTemplate --port 80

Perfect 需要 libcurl 是因为 swift build 获取依赖的时候是使用 curl 来获取代码的,uuid 是因为 Perfect 框架内置函数库所需,而 openssl 则是 Perfect 依赖的库所需。这里使用的是 git clone 的方式获取工程代码,但是也可以通过 COPY 指令复制当前目录下的文件。

Swift 后端开发相关推荐

  1. python开发前端后端区别_一文看懂前端和后端开发

    作为一名开发者,你可能会想:2019 年最好的软件开发技术和编程语言会是什么?它们又是如何被应用在软件开发当中的?如果你在思考这个问题,那就来对地方了.这篇文章将对前端和后端开发技术做一个对比,先从基 ...

  2. 服务器后端开发技术完整学习路线,23张思维导图,自学也能进大厂!

    本文已收录于Github:https://github.com/imcoderlemon/CodeClass 内含原创干货文章,千本计算机电子书,3本LeetCode题解,各类编程资源 大家好,我是柠 ...

  3. 大红大紫的 Golang 真的是后端开发中的万能药吗?

    随着容器编排(Container Orchestration).微服务(Micro Services).云技术(Cloud Technology)等在 IT 行业不断盛行,2009 年诞生于 Goog ...

  4. 一文看懂前端和后端开发

    作为一名开发者,你可能会想:2021 年最好的软件开发技术和编程语言会是什么?它们又是如何被应用在软件开发当中的?如果你在思考这个问题,那就来对地方了.这篇文章将对前端和后端开发技术做一个对比,先从基 ...

  5. 写给后端开发工程师的H5前端开发知识

    一.引言 web发展到目前为止已经有将近30年的历史,在web兴起的早期,并没有前端这个概念.最初所有的开发工作都是由后端开发工程师完成,随着业务越来越复杂,工作量逐渐的增加,项目中的可视化部分和一部 ...

  6. python开发前端后端区别_前端开发与后端开发有什么区别?

    有些人对前端开发和后端开发还存在着疑惑,其实顾名思义,前端开发就是用户看得见摸得着的东西,而后端更多的是与数据库进行交互以及处理相应的业务逻辑.其实主要区别体现在以下两个方面:知识结构与实现和工作职责 ...

  7. python前端开发和后端开发工程师_一文看懂前端和后端开发

    作为一名开发者,你可能会想:2019 年最好的软件开发技术和编程语言会是什么?它们又是如何被应用在软件开发当中的?如果你在思考这个问题,那就来对地方了.这篇文章将对前端和后端开发技术做一个对比,先从基 ...

  8. 前端和后端开发人员比例_前端开发人员vs后端开发人员–实践中的定义和含义

    前端和后端开发人员比例 Websites and applications are complex! Buttons and images are just the tip of the iceber ...

  9. python序列类型包括哪三种映射类型_python序列类型包括哪三种_后端开发

    python中表达式4+0.5值的数据类型为?_后端开发 python中表达式4+0.5值的数据类型为浮点型,因为4是整型,0.5是浮点型,在python中规定整型和浮点型相加,结果是浮点型,这是为了 ...

最新文章

  1. 数字化时代,如何解决企业协同办公的问题?
  2. halcon算子盘点:Chapter 18:元组Tuple
  3. java readline 实现_基于自定义BufferedReader中的read和readLine方法
  4. QT的QGraphicsAnchorLayout类的使用
  5. [css] 元素竖向的百分比设置是相对容器的高度吗?
  6. 用康托展开实现全排列(STL、itertools)
  7. input 底线_社区建设如何帮助组织的底线
  8. JetBrains IDEA实用快捷键
  9. html创建表单用设么,如何使用HTML创建表单的发送
  10. css设置子盒子水平垂直居中(四种方式)
  11. 调用内部类里,在静态类中调用动态方法的问题
  12. MySQL数据库检查修复详解
  13. 微信小程序学习总结(一)——程序文件内容
  14. python面向对象的编程_不会面向对象,肯定学不好Python!简易的面向对象攻略来啦...
  15. xcode自动刷新resource下的文件
  16. 正点原子STM32F103学习笔记(一)
  17. Windows10磁盘分区和扩展
  18. 物联卡中心:物联网卡代理商这么多,我怎么选?
  19. 基于WEB的网上在线图书商城
  20. 真无线蓝牙耳机哪个品牌好?2023年真无线降噪耳机盘点

热门文章

  1. 安卓编译安装python_安卓源码编译环境搭建
  2. 学校计算机实验室实践心得,实验室实践心得体会
  3. flask manage port_nginx+uwsgi+python+flask环境搭建
  4. java 不退出_(Java)如果我在其外面点击,JPopupMenu将不会关闭
  5. es6html模板,js 字符串模板 ES6
  6. springboot + vue_Springboot+VUE---实现简单的websocket
  7. vfp生成菜单时文件不存在_如何在VFP项目中创建菜单
  8. mysql引擎innodb与ndb比较_mysql存储引擎InnoDB 1.1、NDB 7.5对比
  9. java lazy_Java AtomicLong lazySet()用法及代码示例
  10. hercules z/OS 安装 RPG 编译器