在北美的野火季节里,野火季节很好,最好关注当地的空气质量。
让我们从美国EPA的Airnow计划中获取一些实时数据。
即使API请求预算有限,我们也可以根据需要缓存和清爽数据获得活泼的结果。
所有功能都已经内置在增强中。
气动火
https://www.airnowapi.org/aq/observation/zipCode/current/?format=application/json&API_KEY=_SECRET_&zipCode=90210
这就是URL,我们将使用任何给定的邮政编码*。
要求空气质量指数(AQI)
如果在请求的邮政编码附近找到气象站,我们将获得一到三个测量的数组。
{
AQI: 58,
Category: {
Name: 'Moderate',
Number: 2,
},
DateObserved: '2023-06-08 ',
HourObserved: 10,
LocalTimeZone: 'MST',
ParameterName: 'O3',
ReportingArea: 'Denver-Boulder',
StateCode: 'CO',
}
我们需要牢记that this API limits us to 500 requests per hour,但是文档也让我们知道大多数数据点每小时都会更新一次。
因此,如果我们的应用程序将其数据的副本缓存15分钟,我们可以每小时查询125个唯一的邮政编码 - 可能是一个良好的开始,至少直到它流行起来为止
*为简单起见,我坚持使用我们的数据,但是可以使用国际数据。
我建议检查Out IQAir。
增强应用程序中的数据库
要缓存AQI信息,我们需要将数据存放在数据库中。它需要快速!
增强是建立在建筑师之上的,并免费提供所有弧线的超级大国。
这些功能(数据库访问,计划的功能,事件队列等)都是选择加入的,并且不膨胀您已部署的项目。
数据层由AWS的DynamoDB供电,因此设置并获取页面请求的数据非常快。
喜欢,<10ms快。
从数据库操作开始的最简单方法是安装 @begin/data(即使您部署到自己的AWS帐户,也可以与任何弧/增强应用一起使用此库)。
这里是用法的样本:
import data from '@begin/data'
const table = 'pizza'
await data.set([ // save multiple pizzas at once
{table, key: 'bbq-chkn', toppings: ['chicken', 'chz', 'bbq sauce']},
{table, key: 'southwest', toppings: ['chilis', 'red onion', 'corn', 'chz']},
{table, key: 'hawaiian', toppings: ['chz', 'ham', 'pineapple']},
])
const bestPizza = data.get({table, key: 'hawaiian'})
console.log(bestPizza.toppings.at(-1)) // 'pineapple'
缓存API请求
我创建了一个简单的表单组件,该组件可以使用邮政编码参数获取 /美国路由。
然后,我的增强API函数将查找该邮政编码的最新AQI数据。
但是访客可以在一个小时的时间内刷新该页面几次,燃烧在我分配的Airnow API限制中。
因此,当第一次获取数据时,我会以15分钟的时间(TTL)值(TTL)值缓存 - AirNow的数据很少在给定位置更改多次一个小时。
然后,当该用户刷新或其他人请求相同的邮政编码时,我将首先检查数据库,并且仅查询API,如果该邮政编码不存在记录。
import data from '@begin/data'
const { AIRNOW_URL } = process.env
const table = 'aqi'
export async function get({ query: { zip } }) {
if (!zip) return {} // just render the form
const cacheKey = `zip:${zip}`
let aqiData
try {
// first, check the cache
const cached = await data.get({ table, key: cacheKey })
if (cached?.aqiData) {
aqiData = cached.aqiData // continue with data we have
} else {
// no cache, go get some data from AirNow
const response = await fetch(AIRNOW_URL + `&zip=${zip}`)
aqiData = await response.json()
await data.set({ // cache the new data
table,
key: cacheKey,
aqiData,
ttl: Math.round(Date.now() / 1_000) + (60 * 15),
// ↑ 15 minutes from now as seconds since epoch
})
}
} catch (error) {
return { status: 500 }
}
return { json: { aqiData } }
}
批准的没有太多的错误处理,但它是我的API层在这里多么简单的一个很好的例子。
现在,我们可以在由服务器渲染的自定义元素和浏览器本地Web组件供电的视图中介绍此数据!我会涉及创建SVG米的细节(受透气启发),但在这里我所做的工作:
扩展示例
在我的完整示例中,我还根据其IP地址获取访问者可能的邮政编码,并提供由索引路线的结果。
AQI数据不仅缓存,而且邮政编码查找也是如此,因为该服务还具有每日限制。
交互式示例在这里: https://invent-k6b.begin.app/
和源代码: https://github.com/enhance-dev/enhance-example-aqi
您甚至可以看到仪表值的范围: https://invent-k6b.begin.app/test