Kekkonen
making your Clojure web APIs more awesome
ClojuTRE 2015
Tommi Reiman
@ikitommi
Topics
•  API all the things!
•  Challenges
•  Kekkonen
•  Done
API all the things!
•  Clojure(Script) APIs
•  RPC
•  Web APIs
•  REST APIs
•  Future?
Clojure(Script) APIs
•  Namespaces and functions (Vars)
•  Extension via multimethods  protocols
•  Simple, beautiful, no remoting
RPC
•  Expose the tagged Clojure functions outwards
•  Easy remoting
•  refactoring? external clients?
Web APIs
•  Map Clojure functions into http endpoints
•  Thinking in HTTP terms
•  Swagger docs
REST Apis
•  Map Clojure functions into resources
•  Resource containers
•  Swagger docs (yada!)
Future?
•  Datomic  DataScript
•  Falcor/Netflix
–  A JavaScript library for efficient data fetching
•  Relay/Facebook
–  A JAVASCRIPT FRAMEWORK FOR BUILDING
DATA-DRIVEN REACT APPLICATIONS
•  The Web afterTomorrow
–  http://tonsky.me/blog/the-web-after-tomorrow/
©	
  Nikita	
  Prokopov	
  
Hmph.
•  We build complex UIs
•  Reagent is cool
•  Need to do remoting, public api-docs too
•  Business rules need to be enforced both on
server (all)  frontend (part)
–  Shared code is cool, but number of combinations…
•  REST doesn’t even try to solve these issues
CQRS?
making your Clojure web APIs more awesome
Commands  Queries
•  http://martinfowler.com/bliki/CQRS.html
•  Verbs (actions) instead of Nouns (resources)
•  Command log (auditing) as a bonus
•  != Event Sourcing
•  Great for user interactions
–  Rules usually per interaction, not resource
–  Fine-grained à lot’s of actions
©	
  Mar.n	
  Fowler	
  
Commands  Queries
Watch	
  
GiveStar	
  
GetRepository	
  
Fork	
  
Unwatch	
   RemoveStar	
  
ListRespotories	
  
Commands  Queries
Watch	
  
GiveStar	
  
GetRepository	
  
Fork	
  
Unwatch	
   RemoveStar	
  
[repo-­‐id	
  :-­‐	
  s/Str]	
  
check-­‐repo-­‐auth	
  
(watched?	
  false)	
  
	
  
[repo-­‐id	
  :-­‐	
  s/Str]	
  
check-­‐repo-­‐auth	
  
[repo-­‐id	
  :-­‐	
  s/Str]	
  
check-­‐repo-­‐auth	
  
(watched?	
  true)	
  
[repo-­‐id	
  :-­‐	
  s/Str]	
  
check-­‐repo-­‐auth	
  
(starred?	
  false)	
  
[repo-­‐id	
  :-­‐	
  s/Str]	
  
check-­‐repo-­‐auth	
  
[repo-­‐id	
  :-­‐	
  s/Str]	
  
check-­‐repo-­‐auth	
  
(starred?	
  true)	
  
ListRespotories	
  
DIY CQRS lib
Rethinking the APIs
•  Idea
–  Expose simple Clojure functions as message handlers
–  Manage handlers in virtual namespaces
–  Data-driven, no macros, no magic
–  Explicit extensions via protocols, options and meta-data
–  Transports abstracted away, http via ring
•  Lessons learned from ring-swagger  compojure-api
–  Clients as first-class citizens
•  Remote api documentation as data: rules as data
•  Public http api documentation via Swagger
Thanks to
•  Prismatic Schema, (Plumbing)
•  Elegance of fnhouse
•  Ring-swagger
•  Best parts of compojure-api
•  Schema-tools
Concepts
•  Handlers  namespaces
–  Functions with meta-data, contextàresponse
•  Context
–  A message context consumed by the handler
–  Opinion: should contain :data –key with the actual payload
•  Registry
–  Collects and enriches handlers into namespaces
–  Handler invocation  input (pre-)validation
–  Holds global state
•  Ring-adapter
–  http-bindings for invoking the handlers + schema coercion
•  API
–  Wrapping everything up + exception handling
registry	
  
handler	
  
handler	
  
handler	
  
ns	
  
ns	
  
ns	
  
API	
  
Ring-­‐
hander	
  
Swagger
UI	
   O	
  
O	
  O	
  
O	
  
CQRS-­‐API	
  
O	
  
ac.on	
  	
  
context	
  
M	
  
M	
  M	
  
request	
  
Show	
  me	
  
Extensions
•  Registry/Ring/API Options
–  Declare things, plug-in transformers
Extensions
•  Handler  namespace meta-data
–  Explicit way to extend handler functionality at runtime
–  Context enrichment, Authorization,Api-doc info, …
HTTP API
Demo	
  
Client-side?
•  Expose handler data to the clients as clojure (or
JSON) data
–  list all, available or validated
•  Either ask from server or apply the rules for the
local dataset
–  Server: simple, more traffic
–  Client: shared validation-functions, 2+ datasources
TODO
•  Finalize the lib (1-2 months?)
•  Feedback from the community
•  RE-Kekkonen (a reagent template)
•  Async (just rewrite the api-middleware)
•  Event sourcing
Thanks.	
  
hVps://github.com/metosin/kekkonen	
  
kekkonen@metosin.fi	
  	
  
#ring-­‐swagger	
  at	
  Slack	
  
@metosin	
  at	
  TwiVer	
  
	
  
hiring	
  are	
  we.	
  

ClojuTRE2015: Kekkonen - making your Clojure web APIs more awesome

  • 1.
    Kekkonen making your Clojureweb APIs more awesome ClojuTRE 2015 Tommi Reiman @ikitommi
  • 2.
    Topics •  API allthe things! •  Challenges •  Kekkonen •  Done
  • 3.
    API all thethings! •  Clojure(Script) APIs •  RPC •  Web APIs •  REST APIs •  Future?
  • 4.
    Clojure(Script) APIs •  Namespacesand functions (Vars) •  Extension via multimethods protocols •  Simple, beautiful, no remoting
  • 5.
    RPC •  Expose thetagged Clojure functions outwards •  Easy remoting •  refactoring? external clients?
  • 6.
    Web APIs •  MapClojure functions into http endpoints •  Thinking in HTTP terms •  Swagger docs
  • 7.
    REST Apis •  MapClojure functions into resources •  Resource containers •  Swagger docs (yada!)
  • 8.
    Future? •  Datomic DataScript •  Falcor/Netflix –  A JavaScript library for efficient data fetching •  Relay/Facebook –  A JAVASCRIPT FRAMEWORK FOR BUILDING DATA-DRIVEN REACT APPLICATIONS •  The Web afterTomorrow –  http://tonsky.me/blog/the-web-after-tomorrow/ ©  Nikita  Prokopov  
  • 9.
    Hmph. •  We buildcomplex UIs •  Reagent is cool •  Need to do remoting, public api-docs too •  Business rules need to be enforced both on server (all) frontend (part) –  Shared code is cool, but number of combinations… •  REST doesn’t even try to solve these issues
  • 10.
    CQRS? making your Clojureweb APIs more awesome
  • 11.
    Commands Queries • http://martinfowler.com/bliki/CQRS.html •  Verbs (actions) instead of Nouns (resources) •  Command log (auditing) as a bonus •  != Event Sourcing •  Great for user interactions –  Rules usually per interaction, not resource –  Fine-grained à lot’s of actions ©  Mar.n  Fowler  
  • 12.
    Commands Queries Watch   GiveStar   GetRepository   Fork   Unwatch   RemoveStar   ListRespotories  
  • 13.
    Commands Queries Watch   GiveStar   GetRepository   Fork   Unwatch   RemoveStar   [repo-­‐id  :-­‐  s/Str]   check-­‐repo-­‐auth   (watched?  false)     [repo-­‐id  :-­‐  s/Str]   check-­‐repo-­‐auth   [repo-­‐id  :-­‐  s/Str]   check-­‐repo-­‐auth   (watched?  true)   [repo-­‐id  :-­‐  s/Str]   check-­‐repo-­‐auth   (starred?  false)   [repo-­‐id  :-­‐  s/Str]   check-­‐repo-­‐auth   [repo-­‐id  :-­‐  s/Str]   check-­‐repo-­‐auth   (starred?  true)   ListRespotories  
  • 14.
  • 16.
    Rethinking the APIs • Idea –  Expose simple Clojure functions as message handlers –  Manage handlers in virtual namespaces –  Data-driven, no macros, no magic –  Explicit extensions via protocols, options and meta-data –  Transports abstracted away, http via ring •  Lessons learned from ring-swagger compojure-api –  Clients as first-class citizens •  Remote api documentation as data: rules as data •  Public http api documentation via Swagger
  • 17.
    Thanks to •  PrismaticSchema, (Plumbing) •  Elegance of fnhouse •  Ring-swagger •  Best parts of compojure-api •  Schema-tools
  • 18.
    Concepts •  Handlers namespaces –  Functions with meta-data, contextàresponse •  Context –  A message context consumed by the handler –  Opinion: should contain :data –key with the actual payload •  Registry –  Collects and enriches handlers into namespaces –  Handler invocation input (pre-)validation –  Holds global state •  Ring-adapter –  http-bindings for invoking the handlers + schema coercion •  API –  Wrapping everything up + exception handling
  • 19.
    registry   handler   handler   handler   ns   ns   ns   API   Ring-­‐ hander   Swagger UI   O   O  O   O   CQRS-­‐API   O   ac.on     context   M   M  M   request  
  • 20.
  • 21.
    Extensions •  Registry/Ring/API Options – Declare things, plug-in transformers
  • 22.
    Extensions •  Handler namespace meta-data –  Explicit way to extend handler functionality at runtime –  Context enrichment, Authorization,Api-doc info, …
  • 23.
  • 24.
  • 26.
    Client-side? •  Expose handlerdata to the clients as clojure (or JSON) data –  list all, available or validated •  Either ask from server or apply the rules for the local dataset –  Server: simple, more traffic –  Client: shared validation-functions, 2+ datasources
  • 28.
    TODO •  Finalize thelib (1-2 months?) •  Feedback from the community •  RE-Kekkonen (a reagent template) •  Async (just rewrite the api-middleware) •  Event sourcing
  • 29.
    Thanks.   hVps://github.com/metosin/kekkonen   kekkonen@metosin.fi     #ring-­‐swagger  at  Slack   @metosin  at  TwiVer     hiring  are  we.