콘텐츠로 이동

액션 API 참조

추가된 버전: astro@4.15.0

액션을 사용하면 클라이언트 코드 및 HTML 양식에서 호출할 수 있는 타입 안정성을 갖춘 백엔드를 구축할 수 있습니다. 액션을 정의하고 호출하는 모든 유틸리티는 astro:actions 모듈에 의해 노출됩니다. 예시 및 사용 지침은 액션 가이드를 참조하세요.

import {
ACTION_QUERY_PARAMS,
ActionError,
actions,
defineAction,
getActionContext,
getActionPath,
isActionError,
isInputError,
} from 'astro:actions';

타입: ({ accept, input, handler }) => ActionClient

src/actions/index.ts 파일에서 새 액션을 정의하기 위한 유틸리티입니다. 이 함수는 실행할 서버 로직이 포함된 handler() 함수와 런타임에 입력 매개변수를 검사하는 선택적인 input 속성을 받습니다.

src/actions/index.ts
import { defineAction } from 'astro:actions';
import { z } from 'astro:schema';
export const server = {
getGreeting: defineAction({
input: z.object({
name: z.string(),
}),
handler: async (input, context) => {
return `Hello, ${input.name}!`
}
})
}

타입: (input: TInputSchema, context: ActionAPIContext) => TOutput | Promise<TOutput>

액션을 호출할 때 실행할 서버 로직을 포함하는 필수 함수입니다. handler()에서 반환된 데이터는 자동으로 직렬화되어 호출자에게 전송됩니다.

handler()는 사용자 입력을 첫 번째 인수로 받아 호출됩니다. input 유효성 검사기가 설정되어 있으면 사용자 입력은 핸들러로 전달되기 전에 유효성이 검사됩니다. 두 번째 인수는 Astro context 객체의 하위 집합입니다.

반환 값은 devalue 라이브러리를 사용하여 구문 분석됩니다. 이 라이브러리는 Date(), Map(), Set(), URL()의 인스턴스와 JSON 값을 지원합니다.

타입: ZodType | undefined

런타임에 핸들러 입력의 유효성을 검사하기 위해 Zod 유효성 검사기 (예: Zod 객체, Zod 구별된 유니온)를 허용하는 선택적 속성입니다. 액션이 유효성 검사에 실패하면 BAD_REQUEST 오류가 반환되고 handler가 호출되지 않습니다.

input을 생략하면 handler는 JSON 요청의 경우 unknown 타입의 입력을, 양식 요청의 경우 FormData 타입의 입력을 받습니다.

타입: "form" | "json"
기본값: json

액션이 예상하는 형식을 정의합니다.

  • 액션이 FormData를 허용하는 경우 form을 사용합니다.
  • 기본값인 json은 다른 모든 경우에 사용됩니다.

액션이 양식 입력을 허용하는 경우, z.object() 유효성 검사기가 FormData를 타입이 정의된 객체로 구문 분석합니다. 입력을 검증하기 위해 모든 Zod 유효성 검사기를 사용할 수 있습니다.

액션 가이드에서 양식 입력에 유효성 검사기를 사용하는 방법에 대해 자세히 알아보세요. 여기에는 사용 방법에 대한 예시와 특별한 입력을 처리하는 방법도 포함되어 있습니다.

타입: Record<string, ActionClient>

모든 액션을 담고 있는 객체이며, 액션 이름이 키가 되고 해당 액션을 호출하는 함수가 값이 됩니다.

src/pages/index.astro
---
---
<script>
import { actions } from 'astro:actions';
async () => {
const { data, error } = await actions.myAction({ /* ... */ });
}
</script>

Astro가 이 속성을 인식하게 하려면 개발 서버를 다시 시작하거나 astro sync 명령을 실행(s + enter)해야 할 수 있습니다.

타입: (error?: unknown) => boolean

ActionError가 입력 유효성 검사 오류인지 확인하는 데 사용되는 유틸리티입니다. input 유효성 검사기가 z.object()인 경우 입력 오류에는 이름별로 그룹화된 오류 메시지가 있는 fields 객체가 포함됩니다.

양식 입력 오류 가이드에서 isInputError() 사용에 대한 자세한 내용을 참조하세요.

타입: (error?: unknown) => boolean

handler 속성에서 액션이 ActionError를 발생시켰는지 확인하는 데 사용되는 유틸리티입니다. 이는 일반적인 오류의 유형을 좁힐 때 유용합니다.

src/pages/index.astro
---
---
<script>
import { isActionError, actions } from 'astro:actions';
async () => {
const { data, error } = await actions.myAction({ /* ... */ });
if (isActionError(error)) {
// 액션별 오류를 처리합니다.
console.log(error.code);
}
}
</script>

액션 handler가 던지는 오류를 생성하는 데 ActionError() 생성자가 사용됩니다. 이는 발생한 오류 (예: "UNAUTHORIZED")를 설명하는 code 속성과 추가 세부정보가 포함된 선택적 message 속성을 허용합니다.

다음은 사용자가 로그인하지 않았을 때 새 ActionError를 생성하는 예시입니다.

src/actions/index.ts
import { defineAction, ActionError } from "astro:actions";
export const server = {
getUserOrThrow: defineAction({
accept: 'form',
handler: async (_, { locals }) => {
if (locals.user?.name !== 'florian') {
throw new ActionError({
code: 'UNAUTHORIZED',
message: '로그인하지 않았습니다.',
});
}
return locals.user;
},
}),
}

ActionError를 사용하여 액션 결과 처리 시 오류 유형을 좁힐 수도 있습니다.

src/pages/index.astro
---
---
<script>
import { ActionError, actions } from 'astro:actions';
async () => {
const { data, error } = await actions.myAction({ /* ... */ });
if (error instanceof ActionError) {
// 액션별 오류를 처리합니다.
console.log(error.code);
}
}
</script>

타입: ActionErrorCode

사람이 읽을 수 있는 버전의 HTTP 상태 코드를 정의합니다.

타입: string

선택적 속성으로, 오류를 설명합니다. (예: “사용자는 로그인해야 합니다.“)

타입: string

선택적 속성으로, 스택 트레이스를 전달합니다.

타입: (context: APIContext) => AstroActionContext

추가된 버전: astro@5.0.0

미들웨어 핸들러에서 호출되어, 들어오는 액션 요청에 대한 정보를 검색하는 함수입니다. 이 함수는 요청에 대한 정보가 담긴 action 객체, deserializeActionResult() 메서드, 그리고 Astro.getActionResult()가 반환하는 값을 프로그래밍 방식으로 설정하기 위한 setActionResult()serializeActionResult() 함수를 반환합니다.

getActionContext()를 사용하면 미들웨어를 통해 액션 결과를 프로그래밍 방식으로 가져와 설정할 수 있어, HTML 양식의 액션 결과를 유지하고 보안 검사를 추가하여 액션 요청을 제한하는 등의 작업이 가능합니다.

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
const { action, setActionResult, serializeActionResult } = getActionContext(context);
if (action?.calledFrom === 'form') {
const result = await action.handler();
setActionResult(action.name, serializeActionResult(result));
}
return next();
});

타입: { calledFrom: “rpc” | “form”; name: string; handler: () => Promise<SafeResult>; } | undefined

들어오는 액션 요청에 대한 정보를 담고 있는 객체입니다. getActionContext()에서 사용할 수 있으며, 액션의 name, handler, 그리고 액션이 클라이언트 측 RPC 함수(예: actions.newsletter()) 또는 HTML 양식 액션에서 호출되었는지 여부를 제공합니다.

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
const { action, setActionResult, serializeActionResult } = getActionContext(context);
if (action?.calledFrom === 'rpc' && action.name.startsWith('private')) {
// 유효한 세션 토큰 검사
}
// ...
});

타입: "rpc" | "form"

액션이 RPC 함수 또는 HTML 양식 액션을 사용하여 호출되었는지 여부입니다.

타입: string

액션의 이름입니다. 리디렉션 중에 액션 결과의 출처를 추적하는 데 유용합니다.

타입: () => Promise<SafeResult>

결과를 얻기 위해 액션을 프로그래밍 방식으로 호출하는 메서드입니다.

타입: (actionName: string, actionResult: SerializedActionResult) => void

미들웨어에서 Astro.getActionResult()가 반환하는 값을 프로그래밍 방식으로 설정하는 함수입니다. 이 함수에는 액션 이름과 serializeActionResult()로 직렬화된 액션 결과가 전달됩니다. 이 함수를 미들웨어에서 호출하면 Astro 자체의 액션 결과 처리가 비활성화됩니다.

이는 HTML 양식에서 액션을 호출하여 세션에서 결과를 유지하고 로드할 때 유용합니다.

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
const { action, setActionResult, serializeActionResult } = getActionContext(context);
if (action?.calledFrom === 'form') {
const result = await action.handler();
// ... 액션 결과 처리
setActionResult(action.name, serializeActionResult(result));
}
return next();
});
구현 예시를 보려면 Netlify Blob을 사용한 고급 세션 가이드를 참조하세요.

타입: (res: SafeResult) => SerializedActionResult

지속성을 위해 액션 결과를 JSON으로 직렬화합니다. 이는 Map이나 Date와 같은 JSON이 아닌 반환 값과 ActionError 객체를 올바르게 처리하기 위해 필요합니다.

setActionResult()에 전달할 액션 결과를 직렬화할 때 이 함수를 호출하세요:

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
const { action, setActionResult, serializeActionResult } = getActionContext(context);
if (action) {
const result = await action.handler();
setActionResult(action.name, serializeActionResult(result));
}
// ...
});

타입: (res: SerializedActionResult) => SafeResult

serializeActionResult()의 효과를 역전시켜 액션 결과를 원래 상태로 되돌립니다. 이는 직렬화된 액션 결과에서 dataerror 객체에 접근할 때 유용합니다.

타입: (action: ActionClient) => string

추가된 버전: astro@5.1.0

액션을 받아서 URL 경로를 반환하는 유틸리티입니다. 이를 통해 fetch() 작업으로 액션 호출을 직접 실행할 수 있습니다. 또한, 액션을 호출할 때 사용자 지정 헤더와 같은 세부 정보를 제공할 수 있습니다. 그런 다음 액션을 직접 호출한 것처럼 필요에 따라 사용자 지정 형식의 반환된 데이터를 처리할 수 있습니다.

다음 예제는 Authorization 헤더와 keepalive 옵션을 전달하는 정의된 like 액션을 호출하는 방법을 보여줍니다:

src/components/my-component.astro
<script>
import { actions, getActionPath } from 'astro:actions'
await fetch(getActionPath(actions.like), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer YOUR_TOKEN'
},
body: JSON.stringify({ id: 'YOUR_ID' }),
keepalive: true
})
</script>

다음 예제는 sendBeacon API를 사용하여 동일한 like 액션을 호출하는 방법을 보여줍니다:

src/components/my-component.astro
<script>
import { actions, getActionPath } from 'astro:actions'
navigator.sendBeacon(
getActionPath(actions.like),
new Blob([JSON.stringify({ id: 'YOUR_ID' })], {
type: 'application/json'
})
)
</script>

타입: { actionName: string, actionPayload: string }

양식 액션 제출을 처리할 때 Astro 내부적으로 사용하는 쿼리 매개변수 이름을 포함하는 객체입니다.

액션을 사용하여 양식을 제출하면 액션 호출을 추적하기 위해 다음과 같은 쿼리 매개변수가 URL에 추가됩니다.

  • actionName - 호출되는 액션의 이름을 포함하는 쿼리 매개변수입니다.
  • actionPayload - 직렬화된 양식 데이터를 포함하는 쿼리 매개변수입니다.

이 상수는 양식 제출 후 URL을 정리해야 할 때 유용할 수 있습니다. 예를 들어, 리디렉션 중에 액션 관련 쿼리 매개변수를 제거하고 싶을 수 있습니다.

src/pages/api/contact.ts
import type { APIRoute } from "astro";
import { ACTION_QUERY_PARAMS } from 'astro:actions'
export const GET: APIRoute = ({ params, request }) => {
const link = request.url.searchParams;
link.delete(ACTION_QUERY_PARAMS.actionName);
link.delete(ACTION_QUERY_PARAMS.actionPayload);
return redirect(link, 303);
};
import type {
ActionAPIContext,
ActionClient,
ActionErrorCode,
ActionReturnType,
SafeResult,
} from 'astro:actions';

Astro 컨텍스트 객체의 하위 집합입니다. 다음 속성은 사용할 수 없습니다: callAction, getActionResult, props, redirect.

타입:

  • (input?: any) => Promise<SafeResult>
  • { queryString?: string; orThrow: (input?: any) => Promise<Awaited<TOutput>>; }

클라이언트에서 호출되는 액션을 나타냅니다. 입력 데이터를 받아 액션 결과 또는 유효성 검사 오류가 포함된 SafeResult 객체가 담긴 Promise를 반환하는 함수로 사용할 수 있습니다.

다음은 좋아요 수를 증가시키려 할 때 실패하는 경우 if 문을 사용하여 오류 처리를 제공하는 방법을 보여주는 예시입니다.

src/pages/posts/post-1.astro
---
---
<!-- 템플릿 -->
<script>
import { actions } from 'astro:actions';
const post = document.querySelector('article');
const button = document.querySelector('button');
button?.addEventListener('click', async () => {
const { data: updatedLikes, error } = await actions.likePost({ postId: post?.id });
if (error) {
/* 오류 처리 */
}
})
</script>

또는 객체로 사용해 queryString에 접근하거나, 대신 orThrow() 메서드를 호출할 수도 있습니다.

타입: string

양식 액션 URL을 구성하는 데 사용할 수 있는 액션의 문자열 표현입니다. 양식 컴포넌트가 여러 곳에서 사용되지만 제출 시 다른 URL로 리디렉션해야 하는 경우 유용할 수 있습니다.

다음은 queryString을 사용하여 사용자 정의 prop을 통해 양식 action 속성으로 전달할 URL을 구성하는 예시입니다.

src/pages/postal-service.astro
---
import { actions } from 'astro:actions';
import FeedbackForm from "../components/FeedbackForm.astro";
const feedbackUrl = new URL('/feedback', Astro.url);
feedbackUrl.search = actions.myAction.queryString;
---
<FeedbackForm sendTo={feedbackUrl.pathname} />

타입: (input?: any) => Promise<Awaited<TOutput>>

실패 시 오류를 반환하는 대신 오류를 발생시키는 메서드입니다. 이는 오류 처리를 직접 하는 대신 예외를 사용하고자 할 때 유용합니다.

다음은 좋아요 수 증가에 실패했을 때 오류 처리를 건너뛰기 위해 orThrow()를 사용하는 예시입니다.

src/pages/posts/post-1.astro
---
---
<!-- 템플릿 -->
<script>
import { actions } from 'astro:actions';
const post = document.querySelector('article');
const button = document.querySelector('button');
button?.addEventListener('click', async () => {
const updatedLikes = await actions.likePost.orThrow({ postId: post?.id });
})
</script>

타입: string

IANA에서 정의한 표준 HTTP 상태 코드의 유니언 타입으로, 사람이 읽을 수 있는 버전의 대문자 문자열이며, 언더스코어로 구분합니다. (예: BAD_REQUEST 또는 PAYLOAD_TOO_LARGE)

타입: Awaited<ReturnType<ActionHandler>>

액션 핸들러에서 출력 타입을 추출하는 유틸리티 타입입니다. 이는 Promise(핸들러가 비동기인 경우)와 ReturnType을 모두 언래핑하여 실제 출력 타입을 제공합니다. 또한 자체 타입 정의에서 액션의 출력 타입을 참조해야 하는 경우에 유용할 수 있습니다.

다음은 ActionReturnType을 사용하여 contact라는 액션의 예상 출력 타입을 검색하는 예시입니다.

src/components/Form.astro
---
import { actions, ActionReturnType } from 'astro:actions';
type ContactResult = ActionReturnType<typeof actions.contact>;
---

타입: { data: TOutput, error: undefined } | { data: undefined, error: ActionError }

액션 호출 결과를 나타냅니다.

  • 성공 시 data에는 액션의 출력이 포함되고 errorundefined입니다.
  • 실패 시 error에는 유효성 검사 오류 또는 런타임 오류가 포함된 ActionError가 포함되고 dataundefined입니다.
기여하기 커뮤니티 후원하기