함수 간 호출
클라우드 함수끼리 호출하기
함수 간 호출
함수에서 다른 함수를 호출하여 코드를 재사용하고 모듈화할 수 있습니다.
cloud.invoke() 사용
cloud.invoke()를 사용하여 다른 함수를 호출할 수 있습니다:
import cloud from '@imprun/sdk'
import type { FunctionContext } from '@imprun/sdk'
export default async function (ctx: FunctionContext) {
// 다른 함수 호출
const result = await cloud.invoke('send-email', {
body: {
to: 'user@example.com',
subject: '환영합니다',
content: '가입해 주셔서 감사합니다!'
}
})
return {
success: true,
emailSent: result
}
}유틸리티 함수 만들기
공통 로직을 유틸리티 함수로 분리할 수 있습니다:
// functions/utils/index.ts
import { createHash, randomUUID } from 'crypto'
export function md5(data: any) {
return createHash('md5').update(data).digest('hex')
}
export function sha256(data: any) {
return createHash('sha256').update(data).digest('hex')
}
export function uuid() {
return randomUUID()
}
export function formatDate(date: Date) {
return date.toISOString().split('T')[0]
}유틸리티 함수 사용
다른 함수에서 ./로 시작하는 상대 경로로 임포트할 수 있습니다:
// functions/create-user/index.ts
import { uuid, md5, formatDate } from '../utils'
import type { FunctionContext } from '@imprun/sdk'
export default async function (ctx: FunctionContext) {
const { email, password } = ctx.body
const user = {
id: uuid(),
email,
passwordHash: md5(password),
createdAt: formatDate(new Date())
}
console.log('새 사용자:', user)
return {
success: true,
userId: user.id
}
}공유 상태 (Shared State)
cloud.shared를 사용하여 함수들 간에 데이터를 공유할 수 있습니다:
// functions/cache-set/index.ts
import cloud from '@imprun/sdk'
import type { FunctionContext } from '@imprun/sdk'
export default async function (ctx: FunctionContext) {
const { key, value, ttl } = ctx.body
// 데이터 저장
cloud.shared.set(key, value)
// TTL 설정 (선택사항)
if (ttl) {
setTimeout(() => {
cloud.shared.delete(key)
}, ttl * 1000)
}
return {
success: true,
size: cloud.shared.size
}
}// functions/cache-get/index.ts
import cloud from '@imprun/sdk'
import type { FunctionContext } from '@imprun/sdk'
export default async function (ctx: FunctionContext) {
const { key } = ctx.query
const value = cloud.shared.get(key)
return {
found: value !== undefined,
value
}
}메모리 캐시 구현
재사용 가능한 캐시 모듈을 만들 수 있습니다:
// functions/memcache/index.ts
import cloud from '@imprun/sdk'
export function get(key: string) {
return cloud.shared.get(key)
}
export function set(key: string, value: any, ttlSeconds?: number) {
cloud.shared.set(key, value)
if (ttlSeconds) {
setTimeout(() => {
cloud.shared.delete(key)
}, ttlSeconds * 1000)
}
}
export function has(key: string) {
return cloud.shared.has(key)
}
export function keys() {
return Array.from(cloud.shared.keys())
}
export function size() {
return cloud.shared.size
}
export function remove(key: string) {
return cloud.shared.delete(key)
}
export function clear() {
cloud.shared.clear()
}캐시 모듈 사용
// functions/get-user/index.ts
import * as cache from '../memcache'
import cloud from '@imprun/sdk'
import type { FunctionContext } from '@imprun/sdk'
export default async function (ctx: FunctionContext) {
const { userId } = ctx.query
const cacheKey = `user:${userId}`
// 캐시 확인
let user = cache.get(cacheKey)
if (!user) {
console.log('캐시 미스 - DB 조회')
// DB에서 조회
const db = cloud.database()
user = await db.collection('users')
.where({ _id: userId })
.getOne()
// 5분간 캐시
if (user) {
cache.set(cacheKey, user, 300)
}
} else {
console.log('캐시 히트')
}
return user
}인증 미들웨어 패턴
공통 인증 로직을 재사용할 수 있습니다:
// functions/auth-middleware/index.ts
import cloud from '@imprun/sdk'
import type { FunctionContext } from '@imprun/sdk'
export async function requireAuth(ctx: FunctionContext) {
const token = ctx.headers['authorization']?.replace('Bearer ', '')
if (!token) {
throw new Error('인증 토큰이 필요합니다')
}
const payload = cloud.parseToken(token)
if (!payload) {
throw new Error('유효하지 않은 토큰입니다')
}
return payload
}// functions/protected-api/index.ts
import { requireAuth } from '../auth-middleware'
import type { FunctionContext } from '@imprun/sdk'
export default async function (ctx: FunctionContext) {
try {
// 인증 확인
const user = await requireAuth(ctx)
// 비즈니스 로직
return {
message: `안녕하세요, ${user.username}님!`,
data: {
// 보호된 데이터
}
}
} catch (error) {
ctx.response.status(401)
return {
error: error.message
}
}
}비즈니스 로직 분리
복잡한 로직을 별도 함수로 분리:
// functions/user-service/index.ts
import cloud from '@imprun/sdk'
export async function createUser(data: any) {
const db = cloud.database()
return await db.collection('users').add({
...data,
createdAt: new Date()
})
}
export async function getUserById(id: string) {
const db = cloud.database()
return await db.collection('users')
.where({ _id: id })
.getOne()
}
export async function updateUser(id: string, data: any) {
const db = cloud.database()
return await db.collection('users')
.where({ _id: id })
.update(data)
}
export async function deleteUser(id: string) {
const db = cloud.database()
return await db.collection('users')
.where({ _id: id })
.remove()
}// functions/api-users/index.ts
import * as UserService from '../user-service'
import type { FunctionContext } from '@imprun/sdk'
export default async function (ctx: FunctionContext) {
const { method } = ctx
try {
if (method === 'POST') {
const result = await UserService.createUser(ctx.body)
return { success: true, data: result }
}
if (method === 'GET') {
const { id } = ctx.query
const user = await UserService.getUserById(id)
return { success: true, data: user }
}
if (method === 'PUT') {
const { id } = ctx.query
await UserService.updateUser(id, ctx.body)
return { success: true }
}
if (method === 'DELETE') {
const { id } = ctx.query
await UserService.deleteUser(id)
return { success: true }
}
ctx.response.status(405)
return { error: 'Method Not Allowed' }
} catch (error) {
ctx.response.status(500)
return { error: error.message }
}
}체인 함수 호출
여러 함수를 순차적으로 호출:
import cloud from '@imprun/sdk'
import type { FunctionContext } from '@imprun/sdk'
export default async function (ctx: FunctionContext) {
const { email, name } = ctx.body
// 1. 사용자 생성
const userResult = await cloud.invoke('create-user', {
body: { email, name }
})
// 2. 환영 이메일 발송
await cloud.invoke('send-welcome-email', {
body: {
to: email,
name
}
})
// 3. 관리자에게 알림
await cloud.invoke('notify-admin', {
body: {
event: 'new_user',
userId: userResult.id
}
})
return {
success: true,
userId: userResult.id
}
}함수 간 호출은 같은 애플리케이션 내에서만 가능합니다. 다른 애플리케이션의 함수는 HTTP API로 호출해야 합니다.