image
Akan.js
한국어
문서컨벤션레퍼런스Cheatsheet
image
Akan.js
문서컨벤션레퍼런스Cheatsheet
MIT 라이선스 하에 배포되었습니다.
Akan.js 공식 컨설팅 서비스Akansoft
Copyright © 2026 Akan.js 모든 권리 보유.
시스템 관리자bassman
일반
• 인증
• 스키마 설계
• 엣지 컴퓨팅
• 파일 관리
• Single Sign-On
• DataList & Enum
인터페이스
• CRUD
• Endpoint
• Form
관측성
• 로깅
• 의존성 주입
• 에러 처리
• 메트릭
성능
• 캐싱
• 이미지 최적화
• 지연 로딩
• 쿼리
• 큐
• 실시간
개발
• 문서화
• 스크립트
• 도커
• 쿠버네티스
일반
• 인증
• 스키마 설계
• 엣지 컴퓨팅
• 파일 관리
• Single Sign-On
• DataList & Enum
인터페이스
• CRUD
• Endpoint
• Form
관측성
• 로깅
• 의존성 주입
• 에러 처리
• 메트릭
성능
• 캐싱
• 이미지 최적화
• 지연 로딩
• 쿼리
• 큐
• 실시간
개발
• 문서화
• 스크립트
• 도커
• 쿠버네티스
이전
지연 로딩
다음
큐

쿼리

Akan에서 데이터베이스 쿼리는 보통 `document.ts`의 filter에 둡니다. Page와 service는 같은 조건을 매번 만들지 않고 이름 붙은 filter를 호출합니다.
  • 필수 입력은 `filter().arg()`로 받습니다.
  • 선택 입력은 `filter().opt()`로 받습니다.
  • 읽기 쉬운 조건을 위해 `q` helper를 사용합니다.

기본 filter

화면에 필요한 query에서 시작하세요. 예를 들어 project page는 해당 project의 활성 task 목록이 필요합니다.
Project의 task

선택 조건

선택 filter는 사용자가 실제로 선택한 값이 있을 때만 조건을 붙여야 합니다. `q.when`을 쓰면 그 로직이 짧아집니다.
담당자 조건

범위와 OR

기간 조건에는 `q.between`, OR 조건에는 `q.any`를 사용하세요. 날짜 dashboard와 상태 board를 읽기 쉽게 유지할 수 있습니다.
Dashboard 기간

Raw query

Helper로 표현하기 어려운 조건에만 raw query를 사용하세요. 작은 SQL fragment로 유지하고 값은 항상 parameter로 넘기세요.
점수 조건

SQL로 바뀌는 방식

Akan은 대부분의 model 데이터를 document field로 저장하고, filter object를 SQL where clause로 바꿉니다. 개발자는 document 모양으로 쓰고, adaptor가 database용으로 컴파일합니다.
Query helperDocument querySQL 조건문 텍스트
plain equality
{ status: "done" }
json_extract(_doc, '$.status') = ?
q.eq
{ priority: q.eq("high") }
json_extract(_doc, '$.priority') = ?
q.ne
{ status: q.ne("archived") }
json_extract(_doc, '$.status') != ?
q.oneOf
{ status: q.oneOf(["done", "reviewing"]) }
json_extract(_doc, '$.status') IN (?, ?)
q.notOneOf
{ status: q.notOneOf(["archived", "deleted"]) }
json_extract(_doc, '$.status') NOT IN (?, ?)
q.gt
{ score: q.gt(80) }
json_extract(_doc, '$.score') > ?
q.gte
{ progress: q.gte(50) }
json_extract(_doc, '$.progress') >= ?
q.lt
{ retryCount: q.lt(3) }
json_extract(_doc, '$.retryCount') < ?
q.lte
{ dueAt: q.lte(to) }
json_extract(_doc, '$.dueAt') <= ?
q.between
{ updatedAt: q.between(from, to) }
json_extract(_doc, '$.updatedAt') BETWEEN ? AND ?
q.exists
q.exists("assignee")
json_type(_doc, '$.assignee') IS NOT NULL
q.missing
q.missing("deletedAt")
json_type(_doc, '$.deletedAt') IS NULL
q.empty
q.empty("removedAt")
json_extract(_doc, '$.removedAt') IS NULL OR json_extract(_doc, '$.removedAt') = ''
q.has
{ tags: q.has("urgent") }
EXISTS (SELECT 1 FROM json_each(json_extract(_doc, '$.tags')) WHERE value = ?)
q.contains
{ title: q.contains("release") }
json_extract(_doc, '$.title') LIKE ?
q.all
q.all({ project }, { status: "active" })
(json_extract(_doc, '$.project') = ?) AND (json_extract(_doc, '$.status') = ?)
q.any
q.any({ status: "done" }, { status: "reviewing" })
(json_extract(_doc, '$.status') = ?) OR (json_extract(_doc, '$.status') = ?)
q.not
q.not({ status: "archived" })
NOT (json_extract(_doc, '$.status') = ?)
q.when true
q.when(userIds.length, { user: q.oneOf(userIds) })
json_extract(_doc, '$.user') IN (?, ...)
q.when false
q.when(false, { user })
1 = 1
nested path
{ "profile.city": "Seoul" }
json_extract(_doc, '$.profile.city') = ?
array field
{ watchers: q.has(userId) }
EXISTS (SELECT 1 FROM json_each(json_extract(_doc, '$.watchers')) WHERE value = ?)
q.raw
q.raw("json_extract(_doc, '$.score') > ?", [minScore])
(json_extract(_doc, '$.score') > ?)
이 SQL 조각들은 개념을 보여주기 위해 단순화한 예시입니다. Akan은 값을 parameter로 유지하므로, 사용자 입력은 raw SQL 문자열에 붙이지 말고 값으로 전달해야 합니다.
Akan은 왜 대부분의 model 데이터를 JSON document 형태로 저장하나요?
  • 스키마 변경이 가볍습니다. 작은 field를 추가할 때 보통 table migration이 필요 없어서 제품 코드를 더 빠르게 움직일 수 있습니다.
  • Akan은 낮은 수준의 query 튜닝보다 query-first document 설계를 먼저 봅니다. 함께 읽는 데이터는 함께 두어 추가 join과 service glue code를 줄일 수 있습니다.
  • 비즈니스 모델에는 nested setting, history, option, snapshot이 자주 들어갑니다. JSON field는 이런 모양을 자연스럽게 유지하면서도 중요한 경로에는 SQL filter를 적용할 수 있습니다.
  • 목록/상세 화면에 맞춰 의도적으로 denormalize하고, 트래픽이 많아진 경로에만 index를 추가할 수 있습니다.

꿀팁

  • Filter 이름은 화면이나 사용 사례 기준으로 지으세요. `inProject`, `inPeriod`, `forDashboard`처럼요.
  • Page code에는 query 조건 조립을 넣지 않는 것이 좋습니다.
  • Raw SQL보다 helper query를 먼저 사용하세요.
  • 중요 트래픽 경로가 된 filter에는 index를 추가하세요.
쿼리
기본 filter
선택 조건
범위와 OR
Raw query
SQL로 바뀌는 방식
꿀팁