返回介绍

API 端点

发布于 2024-06-05 21:19:57 字数 8294 浏览 0 评论 0 收藏 0

Astro 允许你创建自定义端点来提供任何类型的数据。你可以使用它来生成图像、公开 RSS 文档或将它们用作 API 路由来为你的站点构建完整的 API。

在静态生成的站点中,你的自定义端点在构建时被调用以生成静态文件。如果你选择启用 SSR 模式,自定义端点会变成根据请求调用的实时服务器端点。静态和 SSR 端点的定义类似,但 SSR 端点支持附加额外的功能。

静态文件端点

要想要创建自定义端点,请将 .js.ts 文件添加到 /pages 目录。.js.ts 这样的扩展名将在构建过程中被删除,因此文件名中应包含你要创建的数据的扩展名。例如,文件 src/pages/data.json.ts 将被构建为 API 端点 /data.json

端点导出一个 GET 函数(可选的以 async 导出),该函数接收具有类似于 Astro 全局属性的 上下文对象。在这里,它返回一个带有 nameurl 的 Response 对象,Astro 将在构建时调用它并使用 body 中的内容来生成文件。

// 输出: /builtwith.json
export async function GET({params, request}) {
  return new Response(
    JSON.stringify({
      name: 'Astro',
      url: 'https://astro.build/'
    })
  )
}

从 Astro v3.0 开始,返回的 Response 对象不再需要包含 encoding 属性。例如,生成一个二进制 png 图像:

src/pages/astro-logo.png.ts
export async function GET({ params, request }) {
  const response = await fetch("https://docs.astro.build/assets/full-logo-light.png");  return new Response(await response.arrayBuffer());
}

你还可以使用 APIRoute 类型来约束 API 端点函数:

import type { APIRoute } from 'astro';


export const GET: APIRoute = async ({ params, request }) => {...}

params 和动态路由

端点支持与页面相同的 动态路由 功能。使用中括号包裹参数作为文件名,并导出 getStaticPaths() 函数。然后,你可以使用传递给 API 端点函数的 params 属性访问参数:

src/pages/api/[id].json.ts
import type { APIRoute } from 'astro';


const usernames = ["张三", "李四", "王五"]


export const GET: APIRoute = ({ params, request }) => {
  const id = params.id;
  return new Response(
    JSON.stringify({
      name: usernames[id]
    })
  )
};


export function getStaticPaths () {
    return [
        { params: { id: "0"} },
        { params: { id: "1"} },
        { params: { id: "2"} },
    ]
}

这将在构建时生成三个 JSON 端点:/api/0.json/api/1.json/api/2.json。带端点的动态路由与页面的工作方式相同,但由于端点是一个函数而不是组件,因此 props 是不被支持的。

request

所有端点都会接收 request 属性,但在静态模式下,你只能访问 request.url。它将返回当前端点的完整 URL,其工作方式与 Astro.request.url 对页面的作用相同。

src/pages/request-path.json.ts
import type { APIRoute } from 'astro';


export const GET: APIRoute = ({ params, request }) => {
  return new Response(
    JSON.stringify({
      path: new URL(request.url).pathname
    })
  )
}

服务器端点(API 路由)

静态文件的端点 部分中描述的所有内容均可以在 SSR 模式下使用:文件可以导出一个名为 get 的函数,该函数接收具有类似于 Astro 全局属性的 上下文对象

但是,不同于静态模式,当你使用 server 模式时,端点将在请求时被构建。这解锁了在构建时不可用的新特性,并允许你构建 API 路由以监听请求,并在服务器上安全地执行代码。

相关操作指南: 调用服务器端点

服务器端点可以在不导出 getStaticPaths 的情况下访问 params。服务器端点可以返回一个 Response 对象,其允许你为返回的数据设置 status codesheaders

src/pages/[id].json.js
import { getProduct } from '../db';


export async function GET({ params }) {
  const id = params.id;
  const product = await getProduct(id);


  if (!product) {
    return new Response(null, {
      status: 404,
      statusText: 'Not found'
    });
  }


  return new Response(
    JSON.stringify(product), {
      status: 200,
      headers: {
        "Content-Type": "application/json"
      }
    }
  );
}

这将响应与动态路由匹配的任何请求。例如,如果我们导航到 /helmet.jsonparams.id 将被设置为 helmet。如果我们模拟的数据库中存在 helmet,端点将使用它创建一个包含 product 数据(格式化为 JSON)的 Response 对象,并返回成功的 HTTP状态码。如果没有,它将使用一个 Response 对象返回 404 响应。

在 SSR 模式下,需要提供 Content-Type 头来返回图像。在这种情况下,使用 Response 对象来指定 headers 属性。例如,生成一个二进制 .png 图像:

src/pages/astro-logo.png.ts
export async function GET({ params, request }) {
  const response = await fetch("https://docs.astro.build/assets/full-logo-light.png");
  const buffer = Buffer.from(await response.arrayBuffer());
  return new Response(buffer, {
    headers: { "Content-Type": "image/png" },
  });
}

HTTP 方法

除了 GET 函数,你还可以使用任何 HTTP 方法 作为名称导出函数。当有请求进来时,Astro 会检查该方法并调用相应的函数。

你还可以导出 ALL 函数以匹配任何没有相应导出函数的方法。如果请求方法不匹配,它将重定向到你的网站的 404 页面

src/pages/methods.json.ts
export const GET: APIRoute = ({ params, request }) => {
  return new Response(JSON.stringify({
      message: "This was a GET!"
    })
  )
}


export const POST: APIRoute = ({ request }) => {
  return new Response(JSON.stringify({
      message: "This was a POST!"
    })
  )
}


export const DELETE: APIRoute = ({ request }) => {
  return new Response(JSON.stringify({
      message: "This was a DELETE!"
    })
  )
}


export const ALL: APIRoute = ({ request }) => {
  return new Response(JSON.stringify({
      message: `This was a ${request.method}!`
    })
  )
}
相关操作指南

request

在 SSR 模式下,request 属性返回一个可用的 Request 对象,该对象引用当前请求。这允许你接收数据并检查 headers

src/pages/test-post.json.ts
export const POST: APIRoute = async ({ request }) => {
  if (request.headers.get("Content-Type") === "application/json") {
    const body = await request.json();
    const name = body.name;
    return new Response(JSON.stringify({
      message: "你的名字是:" + name
    }), {
      status: 200
    })
  }
  return new Response(null, { status: 400 });
}

重定向

端点上下文导出一个类似于 Astro.redirectredirect() 函数:

src/pages/links/[id].js
import { getLinkUrl } from '../db';


export async function GET({ params }) {
  const { id } = params;
  const link = await getLinkUrl(id);


  if (!link) {
    return new Response(null, {
      status: 404,
      statusText: 'Not found'
    });
  }

  return Response.redirect(link, 307);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文