clojure at ardoq
Post on 08-May-2015
554 Views
Preview:
DESCRIPTION
TRANSCRIPT
Ardoq.com @ebaxt
Erik Bakstad
Clojure at
Ardoq
Oslo Socially Functional Programmers
Ardoq.com @ebaxt
! 6 years as consultant (finance/telecom)
! Mostly Java & JavaScript professionally
! Discovered Clojure in 2009
! Groovy, Ruby, Python, SML, Racket, Scala …
! CTO & Co-founder of Ardoq
My background
Ardoq.com @ebaxt
AGENDA
! What is Ardoq?
! Why we decided to use Clojure
! Overview Clojure at Ardoq + 2 Cases
! REPL/development environment
! Experience so far / Q&A / Discussions
Ardoq.com @ebaxt
What is Ardoq?
Ardoq.com @ebaxt
We‘re building larger, more complex systems
! Many different “sub-systems“
! Different technologies
! Wide range of integrations
! System-of-systems problem
Ardoq.com @ebaxt
To achieve conceptual understanding we create artifacts
! Documents
! System maps
! Diagrams
! Flowcharts
These artifacts are hard to maintain!
Ardoq.com @ebaxt
Existing tools are either ...
Enterprise architecture software
Very Complex
Word
Not powerfull enough
Excel PowerPoint
Wikis
V isio
Ardoq.com @ebaxt
Ardoq is a documentation platform that offers
! Explorable, “Living” documentation
! Automatically visualizes dependencies and hierarchies
! REST-api for data import/export
! Supports custom visualizations via plugins
Ardoq.com @ebaxt
DEMO
Ardoq.com @ebaxt
Why Clojure?
Ardoq.com @ebaxt
Ardoq.com @ebaxt
Ardoq.com @ebaxt
Ship software
Quickly Fun!
C onsistently (over time)
Quality
Try out different solutions
Understand How it works!
Leverage
Ardoq.com @ebaxt
JavaScript
MongoDB
Clojure
BSON
JSON
{ "firstname": "Erik", "lastname": "Bakstad", "age": 30, "hobby": ["hockey", "cycling"] }
{ "firstname": "Erik", "lastname": "Bakstad", "age": 30, "hobby": ["hockey", "cycling"] }
{ :firstname "Erik" :lastname "Bakstad" :age 30 :hobby ["hockey", "cycling"] }
EDN
Ardoq.com @ebaxt
! Extensive REST-api
! “Version control” on top of MongoDB
! Real-time web backend
! 3-party integrations (recurly, jira, segment.io, +++)
! Attachment service with pluggable storage provider
Stuff we‘ve built in Clojure
Ardoq.com @ebaxt
Architecture
Ardoq.com @ebaxt
Backbone.js !D3.js!jQuery!Require.js! JavaScript-app!
Clojure!backend!
MongoDB!! Redis!
H T TP Websockets SNS!S3!
Segment.io!Mailchimp!Mandrill!Recurly!JIRA!Tarsnap!!
H T TP
TCP
Plugins!JavaDoc / Excel! H T TP
Ardoq.com @ebaxt
api!
com.ardoq.*
utils! service!
gateway!persistence!
MongoDB!!
SNS!S3!
Segment.io!Mailchimp!Mandrill!Recurly!JIRA!!!
hAp://www.infoq.com/presentaGons/DDDIClojure$
Ardoq.com @ebaxt
Libraries
! Carmine
! amazonica
! core.async
! Pantomime
! clj-http/chime/clostach
! Ring/compojure/Liberator
! http-kit/clj-wamp
! Friend/oauthentic/clj-oauth
! clj-schema/antisamy
! Monger/ragtime
Ardoq.com @ebaxt
Testing/debugging
! Started out with midje
! Now using clojure.test
! ring.mock
! Lein test selectors
! Mongodb + redis
! clojure.tools.trace
! IntelliJ with Cursive
! Embedded REPL
! criterium
Ardoq.com @ebaxt
Editor/IDE
! Emacs + Cider
! clojure-mode + paredit
! clojure-test-mode
! clojure-refactor (just started)
! company-cider
Ardoq.com @ebaxt
Infrastructure/monitoring
! S3 (wagon)
! SNS
! Zapier
! Tarsnap
! HipChat
! AWS / on-site
! Ansible /python/bash
! Circle-CI
! Logstash + Kibana
! Pingdom
Ardoq.com @ebaxt
Case 1
REST-api
Ardoq.com @ebaxt
Request Response
Servlet C ontainer Servlet AP I
Ring
Application
Ardoq.com @ebaxt
{:scheme(:http,((:session({}((:request3method(:get,((:query3string("q=hello"((:cookies({}((:uri("/test"((:headers(({"accept3encoding"("gzip,(deflate"}((:body(...}$
(defn%handler([request](...()$
{:status(200((:headers({"Content3Type"((((((((((((("text/plain"}((:body("Hello(World!"}$
Ardoq.com @ebaxt
(defn%middleware([handler]((((()$
Ardoq.com @ebaxt
(defn%middleware([handler]((((fn%[req](((...((((handler(req)(((...())$
Ardoq.com @ebaxt
(defroutes(api((((GET("/"([](...)((((POST("/"([](...))(((def%handler(((((logging((session((security(app))))((((run3jetty(handler({:port(8080}))$
Ardoq.com @ebaxt
(defroutes(api((((GET("/"([](...))(
?
Ardoq.com @ebaxt
Ardoq.com @ebaxt
Liberator
hAp://clojureIliberator.github.io/liberator/$
(defroutes(api((((GET("/"([](...))(
Decision graph
Ardoq.com @ebaxt
Decision graph
hAp://clojureIliberator.github.io/liberator/assets/img/decisionIgraph.svg$
(resource((((((((((:allowed3methods([:get]((((((((((:allowed?((fn%[_]((permission/is3admin?))((((((((((:available3media3types(["application/json"]((((((((((:exists?((fn%[_]({::result(...)((((((((((:handle3ok(::result)))$
Ardoq.com @ebaxt
Authentication
hAps://github.com/cemerick/friend$
! Basic Auth
! Token Auth
! Oauth (Log in with Github, Google, Live Connect)
Ardoq.com @ebaxt
Friend
hAps://github.com/cemerick/friend$
Ardoq.com @ebaxt
Friend
hAps://github.com/cemerick/friend$
{:workflows([(ajax3login)(((((((((((((((token3workflow(:realm("Ardoq"(:credential3fn(...)(((((((((((((((workflows/http3basic(:realm("Ardoq")(((((((((((((((github3oauth(system)(((((((((((((((live3connect3oauth(system)(((((((((((((((google3oauth(system)]((:credential3fn((partial(verify3credentials(system)((:login3uri("/login"((:unauthorized3redirect3uri("/login"((:default3landing3uri("/index.html"}$
Ardoq.com @ebaxt
Middleware
! wrap-impersonate
! wrap-organization
! wrap-session-expiry
! clojure-metrics
Ardoq.com @ebaxt
Case 2
Real-time web
Ardoq.com @ebaxt
API-1! API-2!
Nginx-1! Nginx-2!
Browser-1! Browser-2!POST$/api/component${“name”:$“foo”}$
NoGfy$user$of$BrowserI1’s$POST$
Ardoq.com @ebaxt
Why not use something like Pusher.app or firebase?
Ardoq.com @ebaxt
The Web Application Messaging Protocol
hAp://wamp.ws/$
Ardoq.com @ebaxt
API-1! API-2!
Nginx-1! Nginx-2!
Browser-1! Browser-2!
Websocket + Wamp
Http-kit + cl j-wamp
Autobahn.js + f lash-fal l back
?
Ardoq.com @ebaxt
API-1! API-2!
Nginx-1! Nginx-2!
Browser-1! Browser-2!
Redis PubSub + core.async Redis!
Ardoq.com @ebaxt
Publish!Event! Redis!
Carmine!listener!
Core.async!mult-channel!
(loop! …! (wamp/send-event …)! (recur))!!
Browser-2!Browser-1!
Workspace-event Organization- event
dao!
Ardoq.com @ebaxt
Publish!Event! Redis!
Carmine!listener!
Core.async!mult-channel!
(loop! …! (wamp/send-event …)! (recur))!!
Analytics!
Testing!
dao!
Ardoq.com @ebaxt
REPL
Driven Development
Ardoq.com @ebaxt
http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded
https://github.com/juxt/jig
https://github.com/stuartsierra/component
https://www.youtube.com/watch?v=13cmHf_kt-Q
Ardoq.com @ebaxt
The Clojure experience
So far
Ardoq.com @ebaxt
Ardoq.com @ebaxt
Other benefits
Tiny codebase Fast feedback Libraries (both Java and Clojure) Concurrency
Ardoq.com @ebaxt
Challenges
Dynamic language - tradeoffs Lack of signatures LISP – with great power comes…
Ardoq.com @ebaxt
Thank you!
Questions?
Ardoq.com @ebaxt
THANK YOU!
top related