GraphQL API | 在Hasura DDN上引入TypeScript函数
文章目录
借助 GraphQL API 所需的所有配置,包括 GraphQL 模式、可观察性支持以及高级配置。
为什么选择 Hasura DDN 和 TypeScript 函数?
通过使用简单的 TypeScript 函数,开发者可以快速实现以下功能:
- 将自定义业务逻辑集成到 Hasura DDN 中。
- 执行数据转换并与外部 API 集成。
- 从不受支持的数据源中访问数据。
从头构建 GraphQL 服务器可能面临以下挑战:
1. 编写解析器、类型和数据加载器
手动定义 GraphQL 解析器、类型和数据加载器需要深入了解 GraphQL 模式设计和数据获取策略。这种过程既耗时又容易出错,尤其是在处理复杂数据关系时。
2. 对象关系映射(ORM)
集成 ORM 库可能导致性能瓶颈,并生成低效的 SQL 查询。优化数据库交互需要额外的配置和维护。
3. 访问控制和安全
实现强大的身份验证和授权机制是开发 GraphQL 服务器的关键环节,但也非常复杂。需要遵循安全最佳实践和监管要求。
4. 重复代码的维护成本
手动管理解析器、类型和性能功能会增加开发成本,同时降低开发效率。
Hasura DDN 的 TypeScript 函数优势
Hasura DDN 引入了 TypeScript 函数,简化了 GraphQL 服务器的开发流程。以下是其主要优势:
- 类型安全:通过 TypeScript 自动推断输入和输出类型。
- 内联注释:支持在类型定义上添加注释,自动生成 GraphQL 模式描述。
- 并行执行控制:通过注释指定函数的最大并发执行次数。
- 高级错误处理:通过抛出不同的错误类型,灵活控制用户可见的错误信息。
- 性能优化与调试:内置 OpenTelemetry 支持,便于监控和跟踪函数执行。
- NPM 库支持:可使用任意 NPM 库,简化复杂任务并加速开发。
- 灵活的模式定义:可指定函数为查询或突变。
示例:创建一个简单的 Hello 函数
以下是一个简单的示例,展示如何创建一个名为 hello 的函数:
/** @readonly */
export function hello(name: string): string {
return Hello, ${name};
}
通过以下 GraphQL 查询调用该函数:
query MyQuery {
hello(name: "Sooraj")
}
将函数与数据库字段关联
假设希望将 hello 函数与数据库中的 user 类型关联,可以通过以下方式定义关系:
kind: relationship
version: v1
definition:
name: helloMessage
source: user
target:
command:
name: hello
mapping:
- source: field
path:
- fieldName: name
target:
argumentName: name
查询示例:
query MyQuery {
users {
name
helloMessage
}
}
实际应用:集成 Stripe API
以下示例展示如何使用 Stripe API 查询支付状态:
import Stripe from "stripe";
const stripe = new Stripe("sk_test_XXX");
/**
* @readonly
* @paralleldegree 5
*/
export async function getPaymentStatus(paymentId: string): Promise {
try {
const paymentIntent = await stripe.paymentIntents.retrieve(paymentId, { expand: ["customer"] });
return paymentIntent?.status ?? null;
} catch (error) {
console.error("Error retrieving payment intent:", error);
return null;
}
}
通过以下查询调用该函数:
query MyQuery {
getPaymentStatus(paymentId: "pi_3P8hrySH1GVlVMsJ1bMaCuMo")
}
将函数与订单表关联
通过以下方式将 getPaymentStatus 函数与订单表关联:
kind: relationship
version: v1
definition:
name: paymentStatus
source: orders
target:
command:
name: getPaymentStatus
mapping:
- source: field
path:
- fieldName: paymentId
target:
argumentName: paymentId
查询示例:
query MyQuery {
sales_orders {
id
deliveryDate
paymentStatus
}
}
数据转换示例:去除评论中的脏话
以下示例展示如何使用 bad-words NPM 包清理评论文本中的不当语言:
import { Filter } from "bad-words";
/**
* @readonly
* @paralleldegree 5
*/
export function removeBadWords(reviewText: string): string {
const filter = new Filter();
return filter.clean(reviewText);
}
通过以下方式将函数与评论表关联:
kind: relationship
version: v1
definition:
name: safeText
source: reviews
target:
command:
name: removeBadWords
mapping:
- source: field
path:
- fieldName: text
target:
argumentName: text
查询示例:
query MyQuery {
reviews {
createdAt
safeText
}
}
使用 OpenTelemetry 增强可观察性
Hasura DDN 提供内置的 OpenTelemetry 支持,无需额外配置即可监控和跟踪 Lambda 函数执行。以下是一个示例:
import * as sdk from "@hasura/ndc-lambda-sdk";
import { trace } from "@opentelemetry/api";
import Stripe from "stripe";
const stripe = new Stripe("sk_test_XXX");
const tracer = trace.getTracer("stripeFunction");/**
* @readonly
* @paralleldegree 5
*/
export async function getPaymentStatus(paymentId: string): Promise {
return await sdk.withActiveSpan(tracer, "Retrieve Stripe Payment Status", async () => {
try {
const paymentIntent = await stripe.paymentIntents.retrieve(paymentId, { expand: ["customer"] });
return paymentIntent?.status ?? null;
} catch (error) {
console.error("Error retrieving payment intent:", error);
return null;
}
});
}
错误处理与可见性
Hasura 提供了强大的错误处理机制。以下示例展示如何返回特定的错误信息:
import * as sdk from "@hasura/ndc-lambda-sdk";
/** @readonly */
export function divide(x: number, y: number): number {
if (y === 0) {
throw new sdk.UnprocessableContent("Cannot divide by zero", { x, y });
}
return x / y;
}
API 响应示例:
{
"data": null,
"errors": [
{
"message": "ndc: Cannot divide by zero",
"path": ["divide"],
"extensions": {
"details": {
"x": 10,
"y": 0
}
}
}
]
}
通过 Hasura DDN 的 TypeScript 函数,开发者可以轻松实现复杂的业务逻辑、数据转换以及与外部服务的集成。这种方法不仅简化了开发流程,还提升了系统的可扩展性和性能。
原文链接: https://hasura.io/blog/introducing-typescript-functions-on-hasura-ddn
最新文章
- 如何使用OAuth作用域为您的API添加细粒度权限
- LLM API:2025年的应用场景、工具与最佳实践 – Orq.ai
- API密钥——什么是API Key 密钥?
- 华为 UCM 推理技术加持:2025 工业设备秒级监控高并发 API 零门槛实战
- 使用JSON注入攻击API
- 思维链提示工程实战:如何通过API构建复杂推理的AI提示词系统
- 短信验证码API在Java、Python、PHP中的使用指南
- 免费使用头条热榜API进行数据分析的教程
- 获取 YouTube API Key 密钥的教程与示例
- Python人工智能学习路线(长篇干货)
- 当中医遇上AI:探索“寻艾中医AI开放平台”的创新之旅
- 增值税发票OCR识别API在Java、Python、PHP中的使用教程