Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Protocols and Structs
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Claudio Ortolina
December 02, 2015
Programming
170
1
Share
Protocols and Structs
Processing a data flow in Elixir
Claudio Ortolina
December 02, 2015
More Decks by Claudio Ortolina
See All by Claudio Ortolina
The Perils of Large Files
cloud8421
0
66
Back on your Feet
cloud8421
0
94
Idiomatic Elixir
cloud8421
1
550
GenStage in the Kitchen
cloud8421
4
770
Being a happy developer
cloud8421
2
110
Cooking Lessons with Vim and Tmux
cloud8421
3
290
Rails.vim Projections
cloud8421
0
430
Other Decks in Programming
See All in Programming
UaaL×Androidアプリのメモリ計測 — Memory Profilerの先へ
rio432
0
130
検索設計から 推論設計への重心移動と Recall-First Retrieval
po3rin
5
1.6k
なぜあなたのコードには「コシ」がないのか?〜AI時代に問う、最後まで美味しい設計と戦略〜 #phpconkagawa / phpconkagawa2026
shogogg
0
150
🦞OpenClaw works with AWS
licux
1
340
AgentCore Optimizationを始めよう!
licux
3
210
Claude CodeでETLジョブ実行テストを自動化してみた
yoshikikasama
0
1.2k
cloudnative conference 2026 flyle
azihsoyn
0
130
HTML-Aware ERB: The Path to Reactive Rendering @ RubyKaigi 2026, Hakodate, Japan
marcoroth
0
660
Import assertionsが消えた日~ECMAScriptの仕様はどう決まり、なぜ覆るのか~
bicstone
2
180
WebAssembly を読み込むベストプラクティス 2026年春版 / Best Practices for Loading WebAssembly (Spring 2026)
petamoriken
5
1.1k
Are We Really Coding 10× Faster with AI?
kohzas
0
130
10 Tips of AWS ~Gen AI on AWS~
licux
5
540
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
490
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Darren the Foodie - Storyboard
khoart
PRO
3
3.3k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
160
The Cult of Friendly URLs
andyhume
79
6.9k
Bash Introduction
62gerente
615
210k
YesSQL, Process and Tooling at Scale
rocio
174
15k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
740
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
So, you think you're a good person
axbom
PRO
2
2k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
780
Transcript
PROTOCOLS AND STRUCTS FOR EFFECTIVE DATA FLOW
THE DOMAIN CHECK-IN PROCESS NOTIFY
RECAP ABOUT PROTOCOLS AND STRUCTS
STRUCTS defmodule Checkin do defstruct id: nil, lat: 0.0, lng:
0.0 end
STRUCTS %Checkin{id: "123", lat: 51.50, lng: 0.12} struct(Checkin, id: "123",
lat: 51.50, lng: 0.12) struct(Checkin, %{id: "123", lat: 51.50, lng: 0.12}) struct(Checkin, id: "123", lat: 51.50, lng: 0.12, ignored: true)
PROTOCOLS defprotocol Persistence do def create(thing) end
IMPLEMENTATION defimpl Persistence, for: Checkin do def create(checkin) do %Doc{class:
"Checkin", fields: Map.from_struct(checkin)} |> Repo.create end end
FALLBACK defprotocol Persistence do @fallback_to_any true def create(thing) end
FALLBACK defimpl Persistence, for: Any do def create(thing) do class
= Map.get(thing, :__struct__) |> to_string %Doc{class: class, fields: Map.from_struct(thing)} |> Repo.create end end
USAGE %Checkin{id: "123", lat: 51.50, lng: 0.12} |> Persistence.create
FLOW MESSAGE IDENTIFY LOG PROCESS LOG NOTIFY
FLOW MESSAGE IDENTIFY LOG PROCESS LOG NOTIFY
IDENTIFY { "meta" : { "version" : 1, "topic" :
"checkins", "type" : "create", "request_id" : "15456d4e-782b-11e5-8bcf-feff819cdc9f" }, "data" : { "ref" : "123ASDS", "lat" : 51.50, "lng" : 0.12 } }
IDENTIFY defmodule V1.Checkin.Create do defstruct request_id: nil, ref: nil, lat:
0.0, lng: 0.0 end
IDENTIFY def identify(payload) do case payload["meta"] do %{"version" => 1,
"topic" => "checkins", "type" => "create"} -> V1.Checkins.Create _other -> {:error, :unsupported_payload} end end
POPULATE def populate(struct_name, payload) do request_id = get_in(payload, "meta", "request_id")
struct_attrs = Map.put(payload["data"], "request_id", request_id) Kernel.struct(struct_name, Utils.atomise_map(struct_attrs)) end
ALL TOGETHER NOW message |> identify |> populate(message)
WINS STABLE INTERFACE DEFINES A BOUNDARY EXTENSIBLE INTENTION REVEALING
FLOW MESSAGE IDENTIFY LOG PROCESS LOG NOTIFY
LOG defimpl String.Chars, for: V1.Checkins.Create do def to_string(create_struct) do "type=create
status=accepted request_id=#{create_struct.request_id} ref={create_struct.ref}" end end
LOG def log(item) do :ok = Logger.info item item end
ALL TOGETHER NOW message |> identify |> populate(message) |> log
FLOW MESSAGE IDENTIFY LOG PROCESS LOG NOTIFY
PROCESS defimpl Job, for: V1.Checkin.Create do def process(create_struct) do {:ok,
new_record} = Persistence.create(create_struct) %V1.Checkin.Created{request_id: create_struct.request_id, record: new_record} end end
ALL TOGETHER NOW message |> identify |> populate(message) |> log
|> Job.process
WINS STABLE INTERFACE DEFINES A BOUNDARY EXTENSIBLE INTENTION REVEALING
FLOW MESSAGE IDENTIFY LOG PROCESS LOG NOTIFY
LOG defimpl String.Chars, for: V1.Checkins.Created do def to_string(created_struct) do "type=create
status=processed request_id=#{create_struct.request_id} id={created_struct.record.id}" end end
ALL TOGETHER NOW message |> identify |> populate(message) |> log
|> Job.process |> log
NOTIFY MESSAGE IDENTIFY LOG PROCESS LOG NOTIFY
NOTIFY defimpl Notify, for: V1.Checkin.Created do def topics(created_struct), do: ["checkins",
"users"] def to_message(created_struct) do %Message{request_id: created_struct.request_id, type: :create, data: %{id: created_struct.record.id}} end end
NOTIFY def notify(item) do payload = Notify.to_message(item) topics = Notify.topics(item)
PubSub.broadcast(payload, topics) end
ALL TOGETHER NOW message |> identify |> populate(message) |> log
|> Job.process |> log |> notify
EXECUTION MESSAGE IDENTIFY LOG PROCESS LOG NOTIFY LISTENER PROCESS POOL
PUBSUB POOL
EXTENDING FURTHER ADD NEW STRUCTS IMPLEMENT PROTOCOLS
CORE IDEAS ASSIGN INTENT TO DATA DEFINE FUNCTIONALITY AS PROTOCOLS
DEFINE STRICT BOUNDARIES BETWEEN STEPS
THANK YOU! http://bit.ly/ff-protocols-structs
PLUG ELIXIR, JAVASCRIPT, ELM DEVELOPMENT ELIXIR, JAVASCRIPT, ELM TRAINING ASK
ME ABOUT IT!