text

一个支持 ES3 环境的 querystring

相比于使用 Uniapp / Taro 之类的,我其实更喜欢使用小程序的原生来进行开发。主要是减少中间商赚差价,性能损耗更少一些。当然,也少了不少好用的体验 —— 比如随便引入 NPM 包,好在是现在的小程序开发者工具也提供了 NPM 构建的能力,所以一些基本的使用是没有问题的。

不过,小程序本身环境的特殊性,我在使用 NPM 包的时候还是会有一些谨慎的 —— 要选择尽可能小的、不受平台依赖的包,来缩小小程序的包。所以当我发现一个可以在小程序中使用的包的时候,我就会将其写下来, 以备不时之需。

在涉及到 Web 开发时,一个比较常见的场景是构建 HTTP 中的 QueryString,以便在发送 GET 请求时传递参数。但自己手拼参数还是比较痛苦的,所以用一些 package ,可以有效的提升开发的体验。

TL;DR

你可以在小程序环境中使用 <a href="https://www.npmjs.com/package/querystring-es3">querystring-es3</a> 来进行 querystring 的构建,包的体积不大,可以达到比较好的效果。

const { encode } = require('querystring-es3')

encode({
  page:1,
  pageSize: 10
})
// return 'page=1&pageSize=10'
Code language: JavaScript (javascript)

为什么不是 qs

querystring 的处理包当中,比较出名的除了 node 内置的 querystring 之外,应该就是 qs 了,但实际在使用过程中,小程序的静态分析依赖了 qs,导致开发者使用时要么关闭提醒,要么换包。考虑到我还是希望使用小程序的静态分析,所以就只能替换包了。

待解决问题

  • 实际上我使用 querystring-es3 主要是看到他写的 ES3 compat,但可能其实我可以直接用 query-string ? 需要验证一下。
flat screen TV

用小米电视看电影,感觉挺好

去年买了小米的电视,但一直都闲置在那里,没怎么看。毕竟对于我来说,电脑是一个更加高频度使用的设备,完全没有怎么看过电视。

但过去一年里,没有什么文娱活动,更多都是刷抖音,刷信息流,时间被大量的消耗。在跨年的时候,突发奇想,我是不是可以把电视抱到卧室,在睡前看看电影啥的,毕竟我一直想看电影,但说实话,疫情的原因,让人不太敢和别人在一个密闭空间待两个小时。

说干就干,我把电视抱到卧室,开始用小米电视看电影。

4d2dbe4e85752e901e7446f4570ff4ea
临时搭的架子来看电视

配置好之后,两三天里,我看了好几部之前想看,但没有看的电影 —— 《十万个冷笑话》、《坏蛋联盟》、《小黄人大眼萌 2 :神偷奶爸前传》。

目前我觉得比较好的有:

  1. 我买了小米的电视会员,可以免费看很多电影,这个我很喜欢。虽然部分的影片是需要付费的,但绝大多数是可以免费看。
  2. 更新的很快:小米的影视库资料还行,我想看到的基本都有

不太好的点

  1. 之前我买电视的时候,没怎么花钱,甚至还不如我在用的显示器贵,所以画质很一般、也很容易卡。后续买电视还是要买个更好的品质的。
  2. 无线的网络不太行:毕竟租房,不太好接线,所以看高清的视频就会容易卡,以后自己买房的时候,还是要接网线。

结合小米的广告的尿性,我感觉后续我的最好的方案是一个比较好的传统电视 + 一个电视盒子,这样体验会好点。 Apple TV 买起来!

d2b5ca33bd970f64a6301fa75ae2eb22 3

学会用巧劲,做选择

如果说,一个人最重要的是什么,那便是判断力。有了判断力,做事便有了轻重缓急,有了不同的资源调配。

d2b5ca33bd970f64a6301fa75ae2eb22 3

大部分人终其一生,不做选择,而是随大流,别人做什么,我也做什么。这样带来的结果是终其一生,如浮萍跟随时代和他人的步伐,飘摇不定。

想要摆脱这种不确定性,拥抱确定性,则需要学会做出选择,做那些重要的事情,达成自己的目标。

MacBook Pro near white open book

技术文章格式

在查看一些技术文章的时候,看到一个不错的技术文章的范式,记录一下,这样后续我的技术文章也可以写的更有价值一些,而不仅仅是一个笔记。

以下内容为对应的范式和我的批注。

结构

  1. 简要的 Intro:介绍你在做什么、遇到了什么问题。
  2. tl;dr :总有人不想看长文,对他们友好一些
  3. 目标 + 结果:明确目标既可以帮你明确写作的目标,也可以框定问题的范围
  4. Shortcuts taken :可以快速带走的 intro,也可以理解为是 tldr 的内容
  5. 发现问题、解决问题的过程
  6. 结果
  7. 待解决的问题:在这个过程中你可能会有很多的新问题,可以记录下来,以后慢慢研究
summary

2022 年 12 月月度总结

今年的最后一个月,到了尘埃落定的时刻,也到了一年的总结时刻。今年的一年,是毫无收获,躺平的一年。。。

Objective 1:持续获取现金流,并构建未来收益的现金牛

KR1:投资收益达到 20000 元

12月市场开始回暖,我的基金也开始回暖。终于算是回归了本金。今年的投资收益非常的惨淡,一方面有市场的因素,另一方面,我认为我的 KR 本身有问题。这个到年终总结再讨论吧。

KR2 :单篇稿费突破 6000 元

无变化

KR3 :达成年度预算,支出不超预算

没出门, 也就没超预算。不过这个月有一些紧急支出(指阳了以后,买了大量的储备物资,现在还没吃完。。)

KR4 :构建软件类现金牛业务,预期产生收益 10000 元人民币

暂无进展

Objective 2:提升生活基础设施,构建未来生活好基础

KR1:前往 6 个城市旅行

这个月没有出去玩。。

KR2:进行 20 次文娱活动

没有进行文娱活动。

KR3:借助智能化设备,缩减在家务相关事务上耗费的时间

这个月没有啥变化。

Objective 3 :开拓视野,打造多元行业人才

KR1:写 15 篇书评

暂无进展

KR2:输出关于 API 的 Newsletter 12 封

12月份起草了两篇文章的大纲,但没有写成正式的文章。

KR3 :完成计划中的三本图书的写作

暂无进展。

black and silver laptop computer

几个 Swagger UI 的替代品

Swagger 算是 Code 2 Doc 的默认选项了,各种语言都提供了生成工具,此外官方还提供了一套方便使用的默认 GUI。

d2b5ca33bd970f64a6301fa75ae2eb22 36

不过,Swagger UI 本身其实并不够好用,所以社区就会提供一些 Swagger UI 的替代品,方便大家使用。

ReDoc

ReDoc 是一个前端的开源项目,在 Github 上拥有超过 1W + 的 Star。对我来说,我觉得他最好的点是左中右三栏模式,左侧切换 API,中间查看 API 详情,右侧查看接口调用的 Sample,比 Swagger 官方的 UI 瀑布式的要舒服。

d2b5ca33bd970f64a6301fa75ae2eb22 37

Angular Swagger UI

Angular Swagger UI 同样是一个开源的项目,界面简洁明了,虽然是瀑布式布局,但由于在界面上更加简洁,所以同样可以在同样的屏幕中,获取到更多的信息。

d2b5ca33bd970f64a6301fa75ae2eb22 38
text

使用 Taro 的一些小配置

我自己在使用 Taro 开发小程序的时候,一定会开启的两个配置:

1. 开启压缩

Taro 在预览模式生成的文档比较大,对于小程序的预览来说,不是很友好,所以开发的时候,我经常会打开压缩,以便于在小程序开发者工具进行预览。

修改也比较简单,只需要在你的 package.json 当中加入对应的环境变量 NODE_ENV=production 来支持即可。

diff 见下

d2b5ca33bd970f64a6301fa75ae2eb22 34

2. 开启 webpack 持久化缓存

Taro 可以开启 webpack 的持久化缓存,以便加速 webpack 的构建速度,因此我也会开启这个配置,以提升构建的速度。

d2b5ca33bd970f64a6301fa75ae2eb22 35
d2b5ca33bd970f64a6301fa75ae2eb22 33

《小镇金融学》书摘

Comments

这本书总体和之前看到过什么小岛经济学之类的风格很像,虚构一个环境,并在这个环境中演绎金融学,可以读一读,对于我们所熟悉的金融机构有一些了解。内容总体来说比较薄。

第1章 画中蓬莱

  • 请不要憎恨贪婪与恐惧,恐惧和贪婪是金融市场的永动机,波动的成因无一不是贪婪和恐惧。金融市场以贪婪而始、以恐惧而终,在繁荣与萧条中往复循环。金融市场的魅力恰恰就在于此,没有波动的市场又有什么意义呢

远方即财富

  • 贸易是人类历史上所有重大创新的原动力,有分工才会有贸易,有专业化才会有贸易,贸易确实没有创造什么,但贸易本身就是一种重大的创新。商品从一个人手中流转到另一个人手中,就是因为自己创造不出来(或者创造不划算)。

银钱之行,故曰“银行”

  • “模糊面纱”原则又称“无知之幕”,只有当缔约各方都对未来无知状态时制定的游戏规则才合乎公平。在小镇的故事里,没有人知道未来会是怎样的,只有以最公平的手段保护和惩罚所有人才能确保自己最大限度得到保护,虽然结果不一定公平,但过程肯定公正。

第3章 金融的本性

  • 供给会自行创造需求,这是萨伊定律的结论。

卿本佳人:房地产的金融属性

  • 看着若有所思的轩辕启恒,长孙东阳长叹了一声:“三生三世枕上书,可对现世来说还是那句话,最重要的永远是当下,这才是‘理性’本质,才是俗人的本心。”
  • 一般来说,只要一种商品可以短时间内暴涨(学名“做多”),就具备了最基本的金融属性。在这里我们暂时不考虑暴跌的情况,在金融理论中确实有个名词叫“做空”,也就是赌价格下跌。微观层面确实有人通过“做空”盈利,危机爆发也是因为有人故意“做空”,但这些都是建立在已经有人“做多”(赌价格上涨)的基础上。实际上,宏观层面的“做空”是一个伪概念,打压价格不可能吸引全民投身炒作,毕竟绝大多数人都通过价格上涨才能获利

第5章 走出洪荒

  • 商业银行最基本的原理非常简单,便宜借储户的钱,以更高的价格借给贷款者,金钱高买低卖的商业版本罢了

回不去的从前

  • 通常情况下买房的资金杠杆比率为1∶3—1∶5,也就是说,房价只需要上涨10%,投资者就能赚取30—50%的收益。同样的资金量投入,杠杆可以成倍扩大收益率,当然,也会成倍扩大损失。投资者没有不贪婪的,这是人的本性之一,所以,房地产将永远是投机者的天堂,昨天是,今天是,明天也是

盛衰循环的辩论

  • 经济繁荣的根本原因是大创新,不是货币扩张;同理,经济萧条的根本原因是创新带来的刺激衰减,不是货币收缩,从繁荣到危机不过是将整个过程以金融的方式记录下来罢了。
  • 改变世界的创新在当代经济学中被称为“毁灭型创新”,所谓“毁灭”必定是开天辟地,以新产业毁灭旧产业。新产业必然创造巨大的利润,并对应融资方式的改变,也就是金融革命配合产业革命。金融革命一旦出现,人们便能轻易获得资金,其后模仿者蜂拥而至,投资新产业、投资新产品……“毁灭型创新”注定改变了人类社会生活,工业革命、电气革命、信息技术无不如此。
  • 任何一次“毁灭型创新”都有相似的历程,创新开始的时候会生产奢侈品,随着创新延续成本逐渐降低,普及到草根大众的时候,创新使命就基本结束了

投资银行:人类第二次资金大融合

  • 只有能赚钱的技术才是真正的好技术,也只有实现商业化才能普惠于万众生灵
  • 在金融市场上,如果大家都这么认为,那这件事就一定会发生,这就是所谓的“预期自我强化”
  • 人类第二次资金大融合实现了产业链中的资金流动,造就了投资银行,也对美国经济转型与发展起到了巨大的推动作用。当时投资银行主导的并购中,目标企业拥有互补性资源,注重研发和创新,着力整合各方资源。一旦在大部分行业完成了上下游企业并购,美国工业结构便出现了永久性的变化,国民经济集中化程度空前提高,伴随而来的则是规模效益和垄断利润

再造辉煌

  • 一切的关键,是创新。一次“毁灭型创新”代表着出现一个新的产业,新的产业又代表着形成一个全新的利益格局、一个创新者主导的利益格局。打破一个旧世界,建设一个新世界!旧有利益格局一旦被打破,创新者就会成为新世界的主宰。在创新的路径中,银钱业始终为创新提供了充足的燃料——钱,资本从一个天才转向另一个天才,从一个产业转向另一个产业。只要能在经济分工中掌握最核心的创新,就一定能找到世界上最强大的资金,资金每日梦想着寻找更高的报酬
APILetter

开发者文档的三种内容层次:字典、概览和教程

不知道,你有没有关注过开发者文档的信息结构。下图是 Google Docs 的 API 文档。

89ug0i

在菜单中 Google Docs 提供了 Home、Guides、Reference、Samples、Support。你有没有想过,这些内容为什么如何设计?在我看来,这是开发者文档内容的三种层次。

第一层:解决有没有的问题

典型代表:API Reference

绝大多数开放平台也好,To Developer 产品也罢,首先要解决的问题是让开发者知道我有什么样的能力。而最简单、最直接最高效的方式,便是 API Reference。

各大产品在进行对外开放时,首先准备的便是一套 API Reference。在 API Reference 当中,你可以看到开发者应该如何调用一个 API;某个 API 的入参是什么、出参是什么;如果出现了失败,应该如何处理这些错误。

当一个 API Reference 为开发者提供了简洁、明确、易懂的文档内容之后,开发者基本就可以准备开始进入开发流程了。

Opinionated Notes:RESTFul API 的 API Reference 理论上不应该存在多层级的资源关系。

优秀的 API Reference 参考:

第二层:解决怎么用的问题

典型代表:API Overview、单个业务领域的 API Guides & API Tutorial

作为开放平台,当完成了 API Reference 之后,便算是及格了。但及格不应该是目标,目标应当是卓越。抵达卓越,则需要更多内容的帮助。

API Reference 回答了「能用什么」的问题,但没有解决「如何使用 API」的问题,特别是复杂的业务场景下,同一个业务内可能会需要多个不同的资源来进行 API 的操作,这个时候,如何使用这些资源,并将这些资源包装、关联起来,就成为极具业务属性的 Know How 知识。

举个例子来说,以服务端 OpenAPI 为例,日历的资源就涉及到用户、日历、日程、会议室、参会人、权限管控等多个不同的资源,如何串联这些 API 才能达成你的业务目标,就成为一个非常重要的说明。对于日历的能力熟悉的开发者可能很快就可以找到调通的方式,但对于不够熟悉的,这些 API 之间的串联,可能需要他花费一天,甚至一周的时间才能真正理解背后的含义。如果想要降低开发者调通过个 API 的时间,那么介绍这些不同 API 之间的关系,其在业务系统之中的含义就尤为重要。

如果你对于服务端的 API 感触不深,那么客户端的 API 可能会让你感受更加深刻,以微信小程序的中的蓝牙设备开发为例,如果你作为一个从未开发过蓝牙能力的开发者,看到了蓝牙提供的这一系列 API,只怕马上头皮发麻,需要每一个都看一遍才能理解其含义和价值;在蓝牙这件事上阻塞个半周一周也是常态。

d2b5ca33bd970f64a6301fa75ae2eb22 31

一个好的 API Guide / Tutorial 可以有效的降低开发者在调试这些 API 过程中所耗费的时间。当然,微信也意识到了这个问题,提供了一套非常好的 API 说明

优秀的 Tutorials 参考

第三层:解决场景化使用的问题

典型案例:Code Sample,Demo App,场景化的使用教程

API Tutorials 可以解决的是面向场景化的单个领域的内容。它帮助开发者很好的解决了一个领域内的产品能力的串联。但在实际的业务场景当中,开发者面对的不是已经拆解到 API 粒度的任务,而是面向场景设计的不同问题。对于开发者来说,把场景拆分成 X 个 API 并没那么容易(特别是如果经验不足的时候),因此,一套标准的 Code Sample ,甚至是 Demo App ,都可以帮助开发者快速解决面向场景化的问题。它可能涉及到了客户端、服务端,或者是面向了多个不同的领域。这些内容帮助开发者可以快速 landing。

以飞书开放平台为例,飞书开放平台在开发教程里提供了多个领域、不同方向的场景化教程(虽然还不够多,远远不够),帮助开发者快速完成某个特定领域的功能的开发。

d2b5ca33bd970f64a6301fa75ae2eb22 32

这些内容可能未必能完全满足开发者的需求,但确实可以给开发者一定的借鉴意义,帮助开发者理解整个业务流程和对应场景下的具体的实现,帮助开发者快速完成业务需求。

第三层之后,应该是什么?

前面三层解决了有什么、怎么用的问题,而在整个应用的生命周期当中,怎么用并不是终极问题。下一步需要解决的是如何用好的问题。不过这个问题不在本次阐述的内容当中,所以我们留一个悬念,下次再说。

APILetter

 衡量 API 设计质量的指标 — TTFC/TTFHW

任何一个开放平台类产品,要解决的问题都是如何在现有的平台能力之上,开放一些能力给到第三方开发者,帮助第三方开发者开发应用,拓展体验,如果我们可以降低开发者在完成开放能力接入所需的时间,我们就可以让开发者有更多的时间去构建属于自己的业务逻辑,拓展平台之上的应用生态和开发者体验。

API 的设计质量、文档质量和错误处理信息的质量可以非常明显的影响到 API 的使用体验。但这些体验却很难通过我们在软件工程领域所使用的各种性能指标来衡量。我们可以通过一些专业的、对于 API 有判断能力的人来完成对于 API 质量的评估和优化的引导,但这件事并不利于持续发展和长期迭代。我们需要一个靠谱的指标,来引导我们持续性的、规模化的进行 API 本身的优化和迭代。

上图为 readme.com 提供的 TTFC 介绍

在这个问题上,Slack 给出了自己的答案 —— Time to First Hello World(TTFHW), API 服务提供商 readme.com 则提出了一个类似的概念 Time to First Call(TTFC)。

TTFC/TTFHW 为什么是一个好的指标?

在 TTFC 之前,我相信你或多或少都试过对自己的 API 进行统计和分析。你可能会基于技术工程指标来判断 API 的好与坏;进一步则会通过一些反馈的能力来完成(比如划词反馈、点赞点踩反馈)数据的收集和进一步的分析,你可能会将这些数据进行加权分析,从而得出一个质量评分,用于判断一个 API 的好与坏。

表面上来看,他可以帮助你发现你的 API 当中的不好的点,你可以基于开发者的反馈来快速对 API 当中的一些问题来进行修复,从而提升开发者的开发体验。但这个指标的一个缺点是:它是一个负向反馈的指标。作为 API 的提供者,你拿到这些反馈的时候,它可能已经早已影响了你的大多数开发者,甚至早已令你的开发者十分不快而你却从不知道。不仅如此,如果你的开发者们并不喜欢反馈,你的 API 的问题可能永远都不会暴露出来。

TTFC/TTFHW 如其名所述,记录的是一个开发者第一次调用所需要时长,你可以根据你自己的需要,来设定开发者行为的起点。而终点,则是开发者成功发起一次调用。

相比于需要开发者主动反馈所进行的数据收集,TTFC/TTFHW 的指标不需要开发者做什么,我们可以通过一些技术手段来完成这些信息的收集,从而在第一天开始收集数据。你不需要等自己的 API 有很多开发者之后才能开始进行数据的收集和反馈,只要设计合适的埋点,从 Day 1 就可以获取数据,并基于数据来分析指标和下一步优化的方案。

如何建设 TTFC/TTFHW

TTFC 和 TTFHW 的指标在实际的建设过程中并不容易。其中最大的问题是如何将开发者的行为和实际的调用进行关联。如果你的 API 在前端就可以发生调用,且能够在前端直接调用,还算是简单,可以通过简单的前端埋点来完成数据的建设,并配合开发者在网站上行为的埋点,来分析出具体的 TTFC / TTFHW。

而对于一些服务端的 API,则需要花费更多的心力来建立这些数据,你可能需要将开发者在网站上的行为和其对应的在 API 上的行为进行串联,从而形成一个完整的开发者图景。在最理想的情况下,你的统计系统和你的 API 网关系统上是可以打通的,你可以非常简单的将开发者在网站上的行为与发生在 API 网关系统上的行为进行串联,从而形成一整个从开发者进入网站到开发者了解 API 设计再到开发者真实发生 API 调用当中来完成。

不过,这件事在某些支持以应用身份来调用 API 的开放平台当中来说,就是比较困难的了。因为发生调用的最小单位是应用,而不是某一个人。但也并非绝对无解,你同样可以基于某些指标来圈选一部分开发者,并将这些开发者和实际网关当中产生调用的接口进行串联分析,得出开发者的实际的调用时长。

如何使用 TTFC / TTFHW

当你通过艰辛的数据埋点、数据收集、数据入仓之后,便可以进行数据分析,使用这些数据了。这里分享两个使用这些数据的思路,供你参考。

TTFC/TTFHW 的数据可以从整体数据视角和局部数据视角查看。

当你作为整体数据来查看时,你所拿到的是一个开发者完成整体调用所需的时长。你可以基于开发者的行为,来计算出开发者的 TTFC 所需的时长,和他进入到转化漏斗当中下一步所需的时间,并分析不同时长人群在实际转化率上的差异值,对比这些差异值,并得出判断和下一步的 Action ,优化你的 API 产品的实际体验,提升产品转化率。

上图为 moesif 提供的 TTFC 转化分析图表

当你作为局部数据来查看时,你可以将 TTFC/TTFHW 拆分成若干个不同的阶段,比如网站访问、查找文档、了解鉴权信息、阅读 API 文档、实际发生调用等多个阶段,并对这几个部分的耗时进行分析,从而得出一些定向优化的 Action ,来优化整个网站和 API 的质量,帮助开发者降低调用所需耗费的时长。

建设 TTFC / TTFHW 数据指标的一些建议

在建设 TTFC / TTFHW 的过程中,如果你遇到了困难,不妨试试如下的方式:

  1. 为你的服务端 API 提供一套在线的调试工具,从而让开发者可以在看文档的时候直接调用接口,测试效果。
  2. 如果你的 API 支持以开发者的身份调用,可以试着使用 OAuth 协议,让开发者在看文档的时候直接授权发起调用,并在调用成功之后给出相应的代码的生成。

一个可互动(Interactive)的文档,可以帮助你有效的降低 TTFC/TTFHW。

当然,除了产品本身的优化,你还可以试着提供更多的开发者教程、示例代码,来降低开发者调用你所提供的 API 的难度,优化开发者的体验。