https://hexdocs.pm/ash/get-started.html 을 따라해 보며 Ash 프레임워크의 기본 기능을 배워 본다.
시나리오
간소화된 HelpDesk 시스템을 가정해 보자.
시스템에는 두 개의 리소스가 있다.
Helpdesk.Support.Ticket(티켓)Helpdesk.Support.Representative(담당자)
리소스에는 다음과 같은 액션을 할 수 있다.
- 티켓을 열 수 있다
- 티켓을 닫을 수 있다
- 담당자에게 티켓을 배정할 수 있다
Ash 를 사용하여 구현
새 프로젝트 생성
mix 프로젝트가 없다면 새로 만들 수 있다. Ash 만 사용하는 프로젝트도 만들 수 있으나 향후 JSON API 까지 고려해 Phoenix도 같이 설치 한다.
# install the archive
mix archive.install hex phx_new
mix archive.install hex igniter_new
# use the `--with` flag to generate the project with phx.new and add Ash
mix igniter.new helpdesk --install ash,ash_phoenix --with phx.new && cd helpdesk
igniter 는 Elixir 로 만들어진 코드 생성기 이다. 지금 처럼 프레임워크 초반 세팅이나 버전 업그레이드를 할 때 사용할 수 있다.
첫 번째 도메인
먼저 도메인 폴더와 파일을 만든다.
mkdir -p lib/helpdesk/support && touch $_/ticket.ex && touch lib/helpdesk/support.ex
다음과 같은 폴더 구조일 것이다. lib/helpdesk 내부에 support 도메인이 만들어졌다.

lib/helpdesk/support.ex 파일에 다음 코드를 작성한다.
# lib/helpdesk/support.ex
defmodule Helpdesk.Support do
use Ash.Domain
resources do
resource Helpdesk.Support.Ticket
end
end
Helpdesk.Support 는 Ash.Domain 이고 Helpdesk.Support.Ticket 이라는 Resource 를 가지는 것으로 선언한다.
defmodule Helpdesk.Support.Ticket do
# 이것은 이 모듈을 리소스로 만듭니다
use Ash.Resource, domain: Helpdesk.Support
actions do
# :read 액션의 기본 구현을 사용합니다
defaults [:read]
# 그리고 나중에 커스터마이징할 create 액션
create :create
end
# 속성들은 리소스에 존재하는 간단한 데이터 조각들입니다
attributes do
# `:id`라는 자동 생성되는 UUID 기본 키를 추가합니다
uuid_primary_key :id
# `:subject`라는 문자열 타입 속성을 추가합니다
attribute :subject, :string
end
end
Helpdesk.Support.Ticket 은 Ash.Resource 이고 Helpdesk.Support 도메인에 속한다. 이 리소스를 다루는 몇가지 action 들을 선언할 수 있고 속성 데이터도 정의할 수 있다.
실행
% iex -S mix
iex(1)> Helpdesk.Support.Ticket|> Ash.Changeset.for_create(:create)|> Ash.create!()
Helpdesk.Support.Ticket 리소스를 한 개 만들어 내기 위해 먼저 Changeset 을 만들고 Changeset 을 가지고 Ash.create! 함수를 통해 레코드를 만든다. Ecto.Changeset의 역할을 Ash 에선 Ash.Changeset이 담당하는 것 같다.
warning: Domain Helpdesk.Support is not present in
config :helpdesk, ash_domains: [].
To resolve this warning, do one of the following.
1. Add the domain to your configured domain modules. The following snippet can be used.
config :helpdesk, ash_domains: [Helpdesk.Support]
2. Add the option `validate_config_inclusion?: false` to `use Ash.Domain`
3. Configure all domains not to warn, with `config :ash, :validate_domain_config_inclusion?, false`
warning 발생해도 결과는 얻어지지만 warning 을 없애기 위해 다음 코드를 config.exs 에 추가한다.
# in config/config.exs
import Config
config :helpdesk, :ash_domains, [Helpdesk.Support] # 추가
% iex -S mix
iex(1)> Helpdesk.Support.Ticket|> Ash.Changeset.for_create(:create)|> Ash.create!()
%Helpdesk.Support.Ticket{
id: "7d3d0639-5201-4eb3-9532-a7c837c98eaa",
subject: nil,
__meta__: #Ecto.Schema.Metadata<:built, "">
}
도메인과 리소스를 정의하고 몇가지 선언만 추가해도 기본 뼈대가 되는 기능을 얻을 수 있다.
다음 글에서 계속…