当你知道自己要做什么,才存在适合你的工具。这个时候,你与捷径仅有github的距离 –by 我(偶尔500的后端程序员)

上边这句话,可以看做对“没有银弹”的一种解读

创世初,荆棘遍地,百废待兴,先民试图通过发明一种新的编程语言,来救济陷入沼泽的巨兽,一时间,倚天屠龙,寒光夺目,庙堂、江湖,英雄辈出。

直到后来,人类发现甚至就“php是不是最好的语言”都无法达成一致,拉黑取关,火把相向

人们才痛心疾首地发现

没有银弹

对这段历史有更多兴趣的同学可以自行坠崖,以获上古秘籍《人月神话》于山洞

如果你想要的是,“最强大最好的最快的通用后端”,那你可以关掉网页看冰与火之歌去啦!(这周的更新啦!感谢小钗~)。如果你只是需要一个轻巧的抽象数据存储服务,有一般的身份验证,版本递增的功能,又或者如果你喜欢google的firebase这类东西(什么?你还不知道firebase这种神器?!google!),那么你说不定会喜欢我要推荐的这个东西

kinto

我将kinto看做python的BaaS(Backend as a Services)实现,你可以把它看做一个json server,如果你用过json-server,你应该对它很有好感,json-server是我最喜欢的工具之一,如果你对它不了解可以查看我之前的这篇文章:使用json-server来帮助前后端分离,但是json server仅仅是个作为测试用的server,不具备作为BaaS的能力,首先它没有身份的概念,任何用户可以改写数据

kinto支持用户身份认证,支持细粒度的权限,支持建议的查询,支持数据验证,它与同类产品的比较可以看这里:How does Kinto compare to other solutions,你可以把它看做生产可用的json—server

demo

这是官方的demo,我们也可以自行搭建

test by httpie/postman

1
2
3
echo '{"data": {"description": "Write a tutorial explaining Kinto", "status": "todo"}}' | \
http POST https://kinto.dev.mozaws.net/v1/buckets/default/collections/tasks/records \
-v --auth 'wwj:wwj-secret'

response为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
    "data": {
        "description": "Write a tutorial explaining Kinto",
        "id": "0d59f3db-0c5b-449a-8d12-e3408311ae8b",
        "last_modified": 1464699069634,
        "status": "todo"
    },
    "permissions": {
        "write": [
            "basicauth:d6b8c4bd7214846a9b8c09842a2599bb299df0e68594b69ce18a63c6facec586"
        ]
    }
}

我们来看看我们存下的数据还在不在

1
2
http  https://kinto.dev.mozaws.net/v1/buckets/default/collections/tasks/records \
-v --auth 'wwj:wwj-secret'

哈哈,数据被存下了

我们也可以在kinto-admin中可以使用web界面来管理我们提交的东西

聪明的你一定发现了,我们可以在任何时候任何client里保存这些数据,这样一来,我们可以写没有后端的应用!

如果你熟悉restful风格的接口,上边的请求url你应该好不陌生https://kinto.dev.mozaws.net/v1/buckets/default/collections/tasks/records,buckets/collections和tasks都是命名空间而已,你可以往里构建你的数据框架,就像在数据库里建库建表一样

don’t be shy,别被条条框框束缚,放手去做吧

文档

更多的用法参考kinto.readthedocs.io

关于后端的思考

如果我只是写一个todo mvc应用,为何我需要构建一个后端呢,我要的仅仅是带有用户身份的存储功能,数据模型也很标准,无非是有一个 todo list,这个集合里是一堆item,每个item用json存储

增删改的逻辑完全在web app或是mobile app里实现,后端仅仅是为了永久化和同步设备间的数据,这个需求看去如此常见,数据如此规则,为何不抽象出一个通用的后端

当然早就有人帮你做好啦,这类的东西叫做BaaS

对前端的意义

我将手机端和web前端都视为client,广义上的前端

BaaS让前端开发者一旦熟悉这些API,就可以抽象地使用后端,而不必求助于后端开发者提供接口,如此一来,大多的500就不会发生啦,前端开发者可以独立完成整个应用了!

同时你还获得了横向拓展的能力,由于使用的基本是k-v存储,十分易于拓展,不必担心应用的负载能力。而我们知道,后端新手提供的接口,抗压能力往往很弱的

那么代价呢,代价是BaaS给你提供抽象的后端的时候,让你对它产生了依赖,好比之前parse被收购不久,服务就喊停了。身家性命系于他人,好消息是BaaS已经有不少开源实现了。

对后端的的意义

如果你发现你写的接口多是是标准的RESTful风格,功能上以存储为中心,诸如我最近在做的拓展对象属性,为用户添加profile/头像之类的,业务逻辑清爽简单,那么你也许可以考虑不必自己写整个后端,直接使用BaaS就好了

less code , less bug

kinto的使用笔记

安装

pip

1
2
3
4
5
pip install kinto
kinto init
kinto migrate
kinto start
# kinto --ini /etc/kinto/kinto.ini start #配置

参考Install Kinto

Running in production

Running in production

最佳实践可以参考Deployment good practices

docker

  • sudo docker run -d -p 8888:8888 kinto/kinto-server
    • 之后建议通过docker-compose分离出数据库
  • 访问:http://10.10.100.115:8888/v1/(公司内网)
  • dockerfile
  • 真实的命令:kinto –ini /etc/kinto/kinto.ini migrate && kinto –ini /etc/kinto/kinto.ini start //可以将/etc/kinto/kinto.ini用-v映射出去

###入门教程 offline-first application只有在线时才连接,平时使用js的本地存储功能

push notifications

How to setup push notifications using WebSockets?

使用Pusher来实时推送消息,Pusher采用了websocket来建立长连接

,当然我们也可以搭建Pusher的私有服务:slanger

docker搭建

sudo docker run -d -p 8080:8080 -p 4567:4567 -it –link redis:redis dsninjas/slanger slanger –app_key 765ec374ae0a69f4ce44 –secret your-pusher-secret -r “redis://redis:6379/0”

推送信息(基于python)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import pusher
pusher_client = pusher.Pusher(
  app_id='123456',
  key='765ec374ae0a69f4ce44',
  secret='your-pusher-secret',
  ssl=False,port=4567,host="push_client.tunnel.qydev.com"
)

pusher_client.trigger('test_channel', 'my_event', {'message': '你好'})
# /usr/local/lib/python2.7/dist-packages/pusher/http.py 把200改为202

浏览器的代码为

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<head>
  <title>Pusher Test</title>
  <script src="https://js.pusher.com/3.1/pusher.min.js"></script>
  <script>

    // Enable pusher logging - don't include this in production
    Pusher.logToConsole = true;

    var pusher = new Pusher('765ec374ae0a69f4ce44', {
    wsHost: "127.0.0.1",
    wsPort: "8080",
    wssPort: "8080",
    enabledTransports: ['ws', 'flash']
  });

    var channel = pusher.subscribe('test_channel');
    channel.bind('my_event', function(data) {
      alert(data.message);
    });
  </script>
</head>

更多细节参考pusher的文档,需要注意的是需要替换Host

App-examples

  • kinto-attachment:文件存储
  • kinto-admin:是一个前端界面,可以对接任何kinto后端,用户凭证是安全的,需要https,无法使用http的server,可以直接把官方服务保存到本地即可用http
  • kinto-telegram-wall:消息墙,这是用es6写的一个项目(chrome运行正常,用到了Fetch替代ajax)

permissions

Step by step permissions API tutorial

Custom authentication

kinto是认证后端可插拔的

authentication-github

拓展功能

How to write a Kinto plugin:增加搜索功能

其他的BaaS

上述两者都带有各个平台的SDK,相较kinto,功能完备

我的建议

开发时候,使用云服务,选择不封锁数据的云平台(保障便捷的同时确保可以掌握自己的数据),如果有自行部署的需求,不妨等产品形态定型后再迁移