一个Serverless CMS网站架构

16-06-29 banq
         

这是一个几乎不用服务器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()
<p>

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

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

A Serverless CMS Architecture

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

         

1