在 Expo SDK 50 中引入 React Native API 路由(RFC 说明)

作者:API传播员 · 2025-10-10 · 阅读时间:6分钟

本RFC提议将API路由(即服务器功能)引入React Native生态系统,作为Expo Router v3和即将推出的Expo SDK 50的一部分。目标是让开发者能够直接在React Native项目(支持iOS、Android和Web平台)中以简单且开发者友好的方式编写服务器端逻辑。此功能旨在简化服务器端开发流程提升安全性,并改善开发者体验。


动机

构建服务器端逻辑是移动应用开发中较为复杂的一部分。目前,React Native开发者通常需要在多个代码库之间切换,或者依赖第三方服务来处理服务器端逻辑。

通过将API路由直接集成到React Native项目中,Expo CLI和Expo Router为开发者提供了一种无缝的解决方案,减少了上下文切换,简化了开发流程。


API路由语法

API路由可以通过在项目的app目录中添加一个以+api.ts为后缀的新文件来创建。开发者可以在该文件中导出以下HTTP方法GETPOSTPUTPATCHDELETEHEADOPTIONS。当请求的方法与导出的方法匹配时,相应的函数将会被执行。

以下是一个与OpenAI安全交互的示例:

// app/generate+api.ts
import { ExpoRequest, ExpoResponse } from 'expo-router/server';

export async function POST(req: ExpoRequest): Promise {
  const { prompt } = await req.json();  const json = await fetch(
    'https://api.openai.com/v1/engines/text-davinci-003/completions',
    {
      headers: {
        'Content-Type': 'application/json',
        Authorization: Bearer ${process.env.OPENAI_API_KEY ?? ''},
      },
      method: 'POST',
      body: JSON.stringify({
        prompt,
        max_tokens: 100,
      }),
    }
  ).then(res => res.json());  return ExpoResponse.json(json);
}

开发者可以通过.env文件安全地加载机密信息,例如:

# .env.development
OPENAI_API_KEY=xxxxxx

路由和请求处理

上述API路由文件(app/generate+api.ts)可以通过以下URL访问:http://localhost:8081/generate。开发者可以使用npx expo启动服务,并通过以下命令发起POST请求:

$ curl -X POST -H "Content-Type: application/json" 
  -d '{"prompt":"Hello, my name is Evan"}' 
  http://localhost:8081/generate

Expo Router增强了本地应用中的URL和window.location对象,支持使用相对URL进行请求。例如:

const json = await fetch('/generate').then(res => res.json());

此外,开发者还可以通过Expo CLI的隧道支持,从公共URL提供服务:

npx expo start --tunnel

中间件和运行时环境

一个新的包@expo/server将被引入,用于提供运行服务器端逻辑所需的中间件和运行时环境。


打包机制

服务器端代码将通过Expo CLI和Metro bundler进行打包。这意味着服务器端代码可以使用与客户端代码相同的语言特性。

  • 环境变量:服务器路由可以访问所有环境变量,而不仅仅是以EXPO_PUBLIC_为前缀的变量。
  • 运行时内置功能:在使用Bun或Node.js运行服务器时,相关全局变量可供导入和使用。
  • 错误处理与源码映射:服务器端错误会以与客户端代码相同的方式进行格式化和修复。

每个API路由都会被打包成独立文件,存储在dist/_expo目录中。


请求与响应对象

新的请求和响应对象ExpoRequestExpoResponse将被引入。这些对象基于WinterCG规范,并包含额外的属性以兼容Expo Router。它们的设计灵感来源于Remix、SvelteKit和Next.js 13。

以下是一个错误处理的示例:

// app/blog/[post].ts
import { ExpoRequest, ExpoResponse } from 'expo-router/server';

export async function GET(request: ExpoRequest, { post }: Record) {
  if (!post) {
    return new ExpoResponse('No post found', {
      status: 404,
      headers: {
        'Content-Type': 'text/plain',
      },
    });
  }
  return ExpoResponse.json({ ... });
}
  • 如果请求方法未定义,将自动返回405: Method Not Allowed
  • 如果请求过程中发生错误,将自动返回500: Internal Server Error

本地请求支持

Expo Router将支持在本地环境中使用相对网络请求,从而简化跨Web和原生平台的开发。例如:

fetch('/generate');

在开发环境中,Expo会自动解析服务器地址,但在生产环境中,开发者需要明确指定服务器的URL。未来,开发者可以通过Expo Router配置插件在app.json中定义生产目标。


生产环境支持

与静态模式不同,API路由支持动态路由(如app/[post].tsx),无需额外配置generateStaticParams。此外,这种模式还可以减少构建时的工作量,加快导出速度。

API路由功能可以部署到大多数网络托管服务商。首个Pull Request将支持Express和HTTP服务器,未来将扩展支持更多服务商。


总结

API路由的引入为Expo应用提供了服务器端逻辑的强大支持。这不仅为开发者带来了更高效的开发体验,还为跨平台身份验证和服务器端渲染等功能奠定了基础。未来,Expo还计划支持React服务器组件,进一步提升开发效率

开发者的反馈对于完善此功能至关重要。欢迎提出您的建议和意见!

原文链接: https://blog.expo.dev/rfc-api-routes-cce5a3b9f25d