一个Serverless CMS网站架构

这是一个几乎不用服务器Serverless的内容管理系统网站架构,相比于传统使用WordPress和CraftCMS等内容管理系统可以节省网站的运营管理,相比于维护传统的LAMP架构,Serverless几乎可以没有DevOps。

有时很多客户只是需要一个静态网站,有一个漂亮的图形首页和一些其他静态页面即可,网站一旦发布,几乎很少需要运营维护。那么使用什么技术构建这种静态网站?无疑是Serverless架构,亚马逊的Web服务已经罗列出优点:
1.不需要纠结于操作系统的选择以及安全与管理
2.没有服务器需要配置 监控或扩展
3.没有成本超额造成的风险
4.没有性能考量造成的风险

Contentful就是这样一个Serverless网站,没有管理界面需要开发。

Contentful的JSON数据可以想怎么用就怎么用,有Javascript Ruby和其他流行语言的SDK。

之所以选择JSON作为静态网站的输出,这是因为静态网站能够无需主机托管或虚拟主机等服务器,只要Amazon S3,甚至在Aerobatic上更好,后者能够提供Web主机的更多好处:
1.能够基于Git分支拥有升级的网站
2.可以设置密码保护网站
3.容易添加安全证书
4.容易进行API请求,不必担心CORS
5.节约时间的其他功能

下图是Serverless架构图:


前端使用React.JS, GatsbyJS能够使用ReactJS设计网站,关键代码是在预先构建步骤,从Contentful读取内容项目,然后创建JSON文件在Gatsby站点的文件结构中,这将会转变为一个使用自己定制包装器包装的页面,如下:


#!/usr/bin/env babel-node
require('dotenv').config()
import contentful from 'contentful'
import fs from 'fs-extra-promise'

// Contentful Config
const apiToken = process.env.CONTENTFUL_DELIVERY_API_TOKEN
const spaceId = process.env.CONTENTFUL_SPACE_ID
const client = contentful.createClient({ accessToken: apiToken, space: spaceId })

async function getEntriesByType (contentType, fields) {
const options = { content_type: contentType, fields }

try {
return await client.getEntries(options)
} catch (error) {
console.log('fetching from contentful error: ', error)
return []
}
}

async function renderPost (post) {
try {
return fs.outputFile(
`pages/blog/${post.fields.slug}/index.json`,
JSON.stringify(post, null, 2)
)
} catch (error) {
console.log('Error creating post', error)
return Promise.reject('error')
}
}

async function renderPage (page) {
try {
return fs.outputFile(
`pages/${page.fields.slug}/index.json`,
JSON.stringify(page, null, 2)
)
} catch (error) {
console.log('Error creating page', error)
return Promise.reject('error')
}
}

async function main () {
try {
const posts = await getEntriesByType('post', { published: true })
const postPromises = posts.items.map(post => renderPost(post))
await Promise.all(postPromises)

const pages = await getEntriesByType('page', { active: true })
const pagePromises = pages.items.map(page => renderPage(page))
await Promise.all(pagePromises)
} catch (error) { console.log(error) }
}

main()

理解main函数,它等待从Contentful下中内容项目,然后循环遍历每条项目,在磁盘上为Gatsby创建文件,用于静态网站的构建,这里使用Promise和ES2016的aync/await函数简化异步操作。

现在一个几乎不用服务器主机Serverless的CMS网站系统已经建立运行正常,不用世界上最好语言PHP和LAMP架构了。

A Serverless CMS Architecture

[该贴被banq于2016-06-29 11:21修改过]