My memories of the COVID-19 pandemic in many ways will be the same as most: a makeshift standing desk in the kitchen, a plummet in daily step-count, and a distorted view of hours, days and weeks.
我对COVID-19大流行的记忆在许多方面都与大多数记忆相同:厨房里有一个临时站立的办公桌,每天的步数直线下降,以及小时,天和周的失真视图。
Where my memories differ is when I think about the work I did at Amity during this time. Amity took on many exciting opportunities: helping hospitals to manage their potential COVID patients, helping companies, schools, and universities to work remotely, all whilst enhancing the core Amity products for existing clients.
当我想起这段时间在Amity所做的工作时,我的记忆与众不同 。 Amity带来了许多令人兴奋的机会:帮助医院管理潜在的COVID患者,帮助公司,学校和大学进行远程工作,同时为现有客户增强核心Amity产品。
During the few months that I stood at my desk in the kitchen (a stool placed on top of the table), I worked on 3 projects all with very different tech stacks. I wrote some good code and I wrote some bad code. I lost what feels like years of sleep, but more importantly, I gained what feels like years of experience.
在我站在厨房的桌子上的几个月(桌子上放着一个凳子)的几个月中,我从事了3个项目,每个项目都有不同的技术堆栈。 我写了一些好的代码,我写了一些不好的代码。 我失去了多年的睡眠感觉,但更重要的是,我获得了多年的经验感觉。
I want to share some of these experiences and pass on some useful tips that I picked up along the way.
我想分享其中的一些经验,并传递一些我在学习过程中获得的有用技巧。
第一部分 (Part I)
- GraphQL with Hasura GraphQL与Hasura
- Rapid full-stack development with NextJS version 9 使用NextJS版本9快速进行全栈开发
第二部分 (Part II)
- Build your own translation library 建立自己的翻译库
- Rediscovering higher-order components in React 在React中重新发现高阶组件
第三部分 (Part III)
- Instant messaging with SonarKit SonarKit的即时通讯
- Instant video conferencing with Jitsi Meet 使用Jitsi Meet进行即时视频会议
GraphQL与Hasura (GraphQL with Hasura)
Starting with what’s now my favourite technology: Hasura.
从现在我最喜欢的技术开始: Hasura 。
In its own words:
用自己的话说:
Hasura is an open-source service that can auto-generate a realtime GraphQL API on your Postgres database.
Hasura是一项开源服务,可以在Postgres数据库上自动生成实时GraphQL API。
And this isn’t oversimplifying — give Hasura a Postgres database and in return, you’ll instantly get a GraphQL API that supports complex queries, mutations, bulk actions, and more.
这并不过分简单-为Hasura提供Postgres数据库,作为回报,您将立即获得GraphQL API,该API支持复杂的查询,变异,批量操作等。
It’s as simple as this:
就这么简单:
- Send a query or mutation to the GraphQL API 向GraphQL API发送查询或变异
- The Hasura Engine converts this into a highly optimised SQL statement that runs on your Postgres database Hasura引擎将其转换为在Postgres数据库上运行的高度优化SQL语句
- JSON response gets sent back JSON响应被发送回
![Image for post](https://miro.medium.com/max/9999/1*4dHfzWU2n7C1uzRgC_LPYA.png)
I was introduced to Hasura during project number 3: a completely new application which was primarily a database management system. This meant that a large part of the work was to design and implement the underlying data model.
在项目编号3期间,我被介绍给Hasura:一个全新的应用程序,主要是数据库管理系统。 这意味着大部分工作是设计和实现基础数据模型。
The requirements for the project were changing frequently— how we had modelled some data on Monday might not work for Thursday’s requirement.
该项目的需求经常变化-我们在星期一建模某些数据的方式可能无法满足星期四的需求。
This is where Hasura proved so invaluable — using the Hasura console UI, it’s very simple to add or update tables, relationships and permissions. This meant that anyone in the team could make these sorts of changes, allowing us to just about keep up with the requirements.
这就是Hasura证明无价的地方-使用Hasura控制台UI,添加或更新表,关系和权限非常简单。 这意味着团队中的任何人都可以进行此类更改,从而使我们几乎可以满足要求。
![Image for post](https://miro.medium.com/max/9999/1*PevKvFhDNun1nsQEuYQJGA.png)
The header in the screenshot above shows a glimpse of Hasura’s full features. We made constant use of the built-in GraphiQL editor for exploring the auto-generated GraphQL API, and we built Hasura actions to trigger custom business logic for certain events.
上方屏幕快照中的标题显示了Hasura的全部功能。 我们不断使用内置的GraphiQL编辑器来探索自动生成的GraphQL API,并构建了Hasura操作来触发某些事件的自定义业务逻辑。
使用Hasura的提示 (Tips for using Hasura)
The access control in Hasura is powerful, but also safety conscious. When you add a new column to a table, by default, no roles will have access to read or write from this column.
Hasura中的访问控制功能强大,但也具有安全意识。 默认情况下,当您将新列添加到表中时,没有角色将有权访问此列。
This was one of the reasons we sometimes found ourselves with missing data on the frontend — it was there in the GraphiQL query when run in the Hasura console, but the exact same query from the frontend was coming back without it. This is because on the frontend the query is coming from a logged-in user with an assigned role, and that role might not have permission to see the data. No error messages, just missing data.
这是我们有时会发现前端缺少数据的原因之一-在Hasura控制台中运行时,它在GraphiQL查询中存在,但是前端完全相同的查询却没有了。 这是因为在前端,查询来自具有指定角色的登录用户,并且该角色可能没有查看数据的权限。 没有错误消息,只是缺少数据。
So my tip here is simple: if your frontend is ever missing data, then checking Hasura permissions is a great place to start your debugging.
因此,这里的提示很简单:如果前端缺少数据,那么检查Hasura权限是开始调试的好地方。
![Image for post](https://miro.medium.com/max/9999/1*NHuffxe_Y0nukShDaNOi0g.png)
使用NextJS版本9的快速全栈应用程序 (Rapid full-stack application with NextJS version 9)
NextJS has made it easier than ever to build server-side rendered React applications. But it offers more than just this — with NextJS you can build a frontend, backend, and have all of it deployed to production easily.
NextJS使构建服务器端渲染的React应用程序比以往更加容易。 但是,它不仅提供此功能-借助NextJS,您可以构建前端,后端,并将其轻松部署到生产中。
The second project I moved to was also completely new: an application for Doctors to manage and communicate with potential COVID patients. The application needed a frontend, backend and a database; it needed to be scalable and needed to be in production quickly. Using NextJS, MongoDB Atlas for storage and Vercel for our deployments, we could achieve all of this — especially with version 9 of NextJS.
我转到的第二个项目也是全新的:医生可以管理和与潜在COVID患者进行交流的应用程序。 该应用程序需要前端,后端和数据库。 它需要可扩展,并且需要快速投入生产。 使用NextJS,用于存储的MongoDB Atlas和用于我们的部署的Vercel ,我们可以实现所有这些功能-尤其是使用NextJS版本9。
![Image for post](https://miro.medium.com/max/9999/1*iRe00ocTq_J5in-bExHYEA.jpeg)
Version 9 of NextJS introduced API Routes, a feature so powerful that it allows even a frontend engineer to write reliable backend code — or so I keep telling myself. An API route is just an API endpoint; to build one all you need is a single function that handles the incoming request and provides a response:
NextJS的版本9引入了API Routes,它的功能如此强大,以至于甚至前端工程师都可以编写可靠的后端代码-或者我一直告诉自己。 API路由只是一个API端点; 要构建一个,您只需要一个函数即可处理传入的请求并提供响应:
(req, res) => { // send back some json }
This handler function must be defined in a file within the /pages/api/
directory, and whatever you name the file will map directly to the name of the API endpoint that it generates.
必须在/pages/api/
目录中的文件中定义此处理程序函数,无论您使用什么名称,该文件都将直接映射到它生成的API端点的名称。
The simplicity of API Routes meant that we were able to build backend APIs at the same rate that we were building frontend React components, which given the deadline, had to be very fast.
API路由的简单性意味着我们能够以与构建前端React组件相同的速率来构建后端API,而给定最后期限,它必须非常快。
Our API routes were RESTful endpoints all with mostly the same overall structure:
我们的API路由是RESTful端点,它们的总体结构大致相同:
- A database connection 数据库连接
- Some business logic and/or interaction with the database 一些业务逻辑和/或与数据库的交互
- A JSON response JSON回应
Here’s an example of a route used to update the status of a patient. It demonstrates another great thing about API routes which is their dynamic routing: we’ve defined the request handler function in the file
这是用于更新患者状态的路线的示例。 它展示了API路由的另一个优点,那就是它们的动态路由:我们已经在文件中定义了请求处理函数
/pages/api/user/[patientId]/update-status.js
/pages/api/user/[patientId]/update-status.js
which means that we can call this endpoint with a patient’s ID in the URL (made available to the handler as req.query.patientId
) and have that specific patient updated.
这意味着我们可以使用URL中的患者ID(可以作为处理程序以req.query.patientId
提供给患者)来调用此端点,并更新该特定患者。
Comparing an API route to a typical Express route handler, there are a few immediate differences:
将API路由与典型的Express路由处理程序进行比较,有一些直接的区别:
Connecting to the database must be done at the start of every handler. The database
connect()
function here will actually first check if there is already an active connection, and only if there is not will it attempt to connect.连接到数据库必须在每个处理程序的开始处完成。 实际上,这里的数据库
connect()
函数将首先检查是否已经有活动的连接,只有在没有活动的连接时,它才会尝试连接。Middleware comes in the form of higher-order functions that wrap and enhance the handler — above we’re using
withAuth
middleware that checks for authentication before allowing the request to be handled.中间件以包装和增强处理程序的高阶函数的形式出现-上面我们使用
withAuth
中间件,它在允许处理请求之前检查身份验证。
Both of these differences come from the fact that API routes are deployed as standalone, serverless lambda functions which are only alive when they need to be. Whilst this higher-order function middleware takes some getting used to, this lambda nature makes them highly scalable, and they’re even optimised for a ‘fast’ cold start.
这两种差异均来自以下事实:API路由被部署为独立的无服务器lambda函数,这些函数仅在需要时才处于活动状态。 尽管这种高阶函数中间件需要一些时间来适应,但这种lambda性质使它们具有高度可伸缩性,并且甚至针对“快速”冷启动进行了优化。
使用NextJS的技巧 (Tips for using NextJS)
Most of this was about NextJS version 9 and its API Routes feature, but the best advice I can give is applicable to NextJS in general.
大部分内容与NextJS版本9及其API路由功能有关,但是我能提供的最佳建议通常适用于NextJS。
With NextJS you’re sometimes writing code that will run on both the client and server-side, which tends to require some extra thought given that you may or may not have a window
object.
使用NextJS,有时您会编写可在客户端和服务器端运行的代码,考虑到您可能没有window
对象,这往往需要一些额外的考虑。
Tip: instead of continuously checking for this, write a set of reusable ‘isomorphic’ helper functions that will run seamlessly in both environments.
提示:编写一组可重用的“同构”辅助函数,而不是连续检查这一点,它们将在两种环境中无缝运行。
A good example is an isomorphic redirect function which could look something like this:
一个很好的例子是一个同构重定向函数,看起来可能像这样:
Checking for the existence of a ctx
object and its req
property is a way of checking which environment the code is in: this object will exist on the server-side but not on the client-side.
检查ctx
对象及其req
属性是否存在是检查代码所在环境的一种方式:此对象将存在于服务器端,而不存在于客户端。
Over time you can build a suite of these isomorphic helpers that can even be used across projects, not just for redirects but also for handling cookies, authenticated data fetching, and more.
随着时间的流逝,您可以构建一套这些同构帮助器,甚至可以在整个项目中使用它们,不仅用于重定向,还可以用于处理Cookie,已验证的数据提取等。
翻译自: https://medium.com/@cp.vibert/software-engineering-at-eko-pandemic-edition-part-i-75b8f4f578e6