# Ash: 7 - Code Interfaces
```elixir
Application.put_env(:ash, :validate_domain_resource_inclusion?, false)
Application.put_env(:ash, :validate_domain_config_inclusion?, false)
Mix.install([{:ash, "~> 3.0"}], consolidate_protocols: false)
```
## Code Interfaces
### In this tutorial you will add a Code Interface
In previous tutorials you always used `Changesets` directly to CRUD on resources.
While this is a perfectly valid way of handling CRUD operations, Ash provides [Code Interfaces](https://hexdocs.pm/ash/code-interfaces.html) to make this more ergonomic for you.
The code interface can be defined on the resources *or* the domain. In this example, we will define it on the domain.
You will add 3 code interfaces for:
* Creating a representative
* Opening a ticket
* Assigning a representative
For each resource you want to add a code interface to, inside that resource definition on the domain, you will place "definitions".
For example:
```elixir
resource MyApp.Tweet do
define :create_tweet, args: [:content]
end
```
Then add the 3 interfaces by defining the following inside the `Ticket` resource's block:
* `define :assign_ticket, args: [:representative_id], action: :assign`
* `define :open_ticket, args: [:subject, :description], action: :open`
And the following inside the `Representative` resource's block.
* `define :create_representative, args: [:name], action: :create`
Show Solution
```elixir
resource Tutorial.Support.Ticket do
define :assign_ticket, args: [:representative_id], action: :assign
define :open_ticket, args: [:subject, :description], action: :open
end
resource Tutorial.Support.Representative do
define :create_representative, args: [:name], action: :create
end
```
### Enter your solution
```elixir
defmodule Tutorial.Support.Ticket do
use Ash.Resource,
domain: Tutorial.Support,
data_layer: Ash.DataLayer.Ets
actions do
defaults [:read]
create :open do
accept [:subject, :description]
end
update :close do
change set_attribute(:status, :closed)
end
update :assign do
accept [:representative_id]
end
end
attributes do
uuid_primary_key :id
attribute :subject, :string, allow_nil?: false
attribute :description, :string, allow_nil?: true
attribute :status, :atom do
constraints one_of: [:open, :closed]
default :open
allow_nil? false
end
create_timestamp :created_at
update_timestamp :updated_at
end
relationships do
belongs_to :representative, Tutorial.Support.Representative
end
end
defmodule Tutorial.Support.Representative do
use Ash.Resource,
domain: Tutorial.Support,
data_layer: Ash.DataLayer.Ets
actions do
defaults [:read]
create :create do
accept [:name]
end
end
attributes do
uuid_primary_key :id
attribute :name, :string
end
end
defmodule Tutorial.Support do
use Ash.Domain
resources do
resource Tutorial.Support.Ticket do
# <-- Add ticket code interface here
end
resource Tutorial.Support.Representative do
# <-- Add representative code interface here
end
end
end
```
## Using the Code Interfaces
Create a Representative, but instead of using a changeset, use the code interface you created.
You can use a code interface by calling `Tutorial.Support.create_representative!/1` with the desired name.
Set the name to `Joe Armstrong` and store it in a `joe` variable.
Show Solution
```elixir
joe = Tutorial.Support.create_representative!("Joe Armstrong")
```
```elixir
```
Create a Ticket with the created code interface.
Call `Tutorial.Support.open_ticket!/2` with a `subject` and `description` and store the result in a `ticket` variable.
Show Solution
```elixir
ticket = Tutorial.Support.open_ticket!("I can't find my hand!", "I think someone stole it.")
```
```elixir
```
Assign the Representative `joe` to the Ticket using the code Interface.
Use `Tutorial.Support.assign_ticket!/2`.
Show Solution
```elixir
Tutorial.Support.assign_ticket!(ticket, joe.id)
```
```elixir
```