Join Blog Training ABOUT US We are a small house of Programmers with focus on delivering high quality software. We believe that successful software projects are made by small teams of capable individuals with high-productivity tools. Our customers vary from large enterprises and IT service providers to lean product development organizations. We focus on solving customers' challenges together and with the best possible tools. We use lean & agile methods with modern software development tools including, but not limited to Clojure, ClojureScript, JavaScript, Scala, PostgreSQL and MongoDB. Besides working with customer projects, we do inhouse product, service development, develop and maintain Open Source libraries organize community events (such as ClojuTRE), give out Tech Talks, work with Universities and offer Clojure trainings in Finland. Also have had fun playing with gadgets and some nice Brews Our world headquarters is located at Tampere Central Square, Aleksis Kiven katu 24 B 37, Tampere. We also have southern Finland branch at Bulevardi 14, 5th floor, Helsinki. Current status: mostly Clojure & Clojurescript. SERVICES Consulting Software development Clojure training BLOG The Curious Case of ClojuTRE 2016 Compojure-api 1.0.0 Is Out Hello World OPEN SOURCE Here are few selected libraries we have open-sourced on GitHub compojure-api Sweet web apis with Compojure & Swagger ring-swagger Swagger Spec for Clojure Web Apps schema-tools Common Clojure(Script) utilities for working with Prismatic Schemas TAMPERE TOMMI REIMAN Programmer Worked over 17 years as a programmer and hands-on architect, mostly in the telco sector. Architected large SOA, integration and self-service systems and rammed up lean development teams & processes. Into clean, lean and functional - mostly in Clojure & Clojurescript. MIKKO HEIKKILÄ Programmer, CEO Over 16 years of professional software development and consulting, headed large-scale system integration & web projects, programmed, coached development teams and knows all that Agile jazz. JARPPE LÄNSIÖ Programmer When not plotting for world domination with quadrocopters he helps Finnish industry and government organisations to adopt Clojure. 23 years of professional experience in developing business-critical software. JUHO TEPERI Programmer Despite the young age, has solid attitude and awesome skills on fp, web, mobile and Linux. TUUKKA KATAJA Programmer A well-mannered programmer with exquisite skills in web development with JavaScript, ClojureScript and Clojure. MATTI NIEMINEN Programmer Programming jack-of-all-trades with background in developing mission-critical systems for defence and health care. Also in Clojure. JARI VASELL Consultant Jari helps our customers with discovery of new services and revitalization of old ones. He has vast experience in business process digitalization, especially in field service management, smart city and IoT contexts. PETRI TUOMINEN UX virtuoso Petri has extensive knowledge of how to create engaging and smooth user experience for real end-users, be it complex enterprise systems or lean start-up apps. HELSINKI MIIKA PIHLAJA Programmer With background from both academia and industry, knows his applied maths, data-analysis, statistics & machine learning, but is also proficient full-stack web-app developer. LASSI IMMONEN Programmer Pragmatic problem solver and digital craftsman with over 16 years of software development experience. Likes to use good and productive development tools from backend to user interfaces but most importantly, loves to create something useful for the end users. MIIKKA KOSKINEN Programmer Miikka believes that the judicious use of functional programming, code review, and careful thinking can salvage any codebase. Even in Python. JOIN US? If you are looking for new challenges and programming is your thing, check out our open positions. Tweets by @metosin CONTACT Tampere Aleksis Kiven katu 24 B 37 33200 Tampere Helsinki Bulevardi 14, 5th floor 00120 Helsinki Metosin Ltd. Business-id: 2341528-4 Emails: firstname.lastname@metosin.fi Phone: +358 50 326 2280 # Mikko Media assets (defn- destructure-compojure-api-request "Returns a vector of four elements: - pruned path string - new lets list - bindings form for compojure route - symbol to which request will be bound" [path lets arg] (let [path-string (if (vector? path) (first path) path)] (cond ;; GET "/route" [] (vector? arg) [path-string lets (into arg [:as +compojure-api-request+]) +compojure-api-request+] ;; GET "/route" {:as req} (map? arg) (if-let [as (:as arg)] [path-string (conj lets +compojure-api-request+ as) arg as] [path-string lets (merge arg [:as +compojure-api-request+]) +compojure-api-request+]) ;; GET "/route" req (symbol? arg) [path-string (conj lets +compojure-api-request+ arg) arg arg] :else (throw (RuntimeException. (str "unknown compojure destruction syntax: " arg)))))) (defn restructure [method [path arg & args] {:keys [routes]}] (let [method-symbol (symbol (str (-> method meta :ns) "/" (-> method meta :name))) method-kw (if routes :any (-> method meta :name str str/lower-case keyword)) [parameters body] (extract-parameters args) wrap (or routes 'do) [lets letks responses middlewares] [[] [] nil nil] [path-string lets arg-with-request arg] (destructure-compojure-api-request path lets arg) {:keys [lets letks responses middlewares parameters body]} (reduce (fn [acc [k v]] (restructure-param k v (update-in acc [:parameters] dissoc k))) (map-of lets letks responses middlewares parameters body) parameters) pre-lets [+compojure-api-coercer+ `(memoized-coercer)] form `(~wrap ~@body) form (if (seq letks) `(letk ~letks ~form) form) form (if (seq lets) `(let ~lets ~form) form) form (if (seq middlewares) `(route-middlewares ~middlewares ~form ~arg) form) form `(~method-symbol ~path ~arg-with-request ~form) form (if responses `(body-coercer-middleware ~form ~+compojure-api-coercer+ ~responses) form) form (if (seq pre-lets) `(let ~pre-lets ~form) form) ;; for routes, create a separate lookup-function to find the inner routes child-form (if routes (let [form `(~wrap ~@body) form (if (seq letks) `(dummy-letk ~letks ~form) form) form (if (seq lets) `(dummy-let ~lets ~form) form) form `(fn [~'+compojure-api-request+] ~form) form (if (seq pre-lets) `(let ~pre-lets ~form) form)] form))] `(let [childs# ~(if routes [`(~child-form {})] [])] (routes/create ~path-string ~method-kw ~parameters childs# ~form))))