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
Clojure.specを活用したコード・ファーストスタイルのRESTサービス開発
Search
Kenji Nakamura
October 05, 2017
Technology
1
740
Clojure.specを活用したコード・ファーストスタイルのRESTサービス開発
(増席) 教養としてのClojure - そろそろ学んでおきたい2017年秋
https://d-cube.connpass.com/event/67567/presentation/
Kenji Nakamura
October 05, 2017
Tweet
Share
Other Decks in Technology
See All in Technology
なぜarray_firstとarray_lastは採用、 array_value_firstとarray_value_lastは 見送りだったか / Why array_value_first and array_value_last was declined, then why array_first and array_last was accpeted?
cocoeyes02
0
130
RGBに陥らないために -プロダクトの価値を届けるまで-
righttouch
PRO
0
120
FastMCP OAuth Proxy with Cognito
hironobuiga
3
220
やさしいとこから始めるGitHubリポジトリのセキュリティ
tsubakimoto_s
3
1.9k
OCI技術資料 : ロード・バランサ 概要 - FLB・NLB共通
ocise
4
27k
【Oracle Cloud ウェビナー】データ主権はクラウドで守れるのか?NTTデータ様のOracle Alloyで実現するソブリン対応クラウドの最適解
oracle4engineer
PRO
3
120
互換性のある(らしい)DBへの移行など考えるにあたってたいへんざっくり
sejima
PRO
0
230
AI時代のIssue駆動開発のススメ
moongift
PRO
0
280
ブラックボックス化したMLシステムのVertex AI移行 / mlops_community_62
visional_engineering_and_design
1
210
SSoT(Single Source of Truth)で「壊して再生」する設計
kawauso
2
390
Why we keep our community?
kawaguti
PRO
0
320
ハーネスエンジニアリング×AI適応開発
aictokamiya
1
470
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
528
40k
Discover your Explorer Soul
emna__ayadi
2
1.1k
A Soul's Torment
seathinner
5
2.5k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
230
GitHub's CSS Performance
jonrohan
1032
470k
SEO for Brand Visibility & Recognition
aleyda
0
4.4k
Faster Mobile Websites
deanohume
310
31k
[SF Ruby Conf 2025] Rails X
palkan
2
860
The Language of Interfaces
destraynor
162
26k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
68
38k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
440
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
1
490
Transcript
を活用したコード・ファーストスタ を活用したコード・ファーストスタ イルの イルの サービス開発 サービス開発 - D3 Meetup 教養としてのClojure
2017/10/4 - 株式会社シグニファイア 代表 中村研二
自己紹介 自己紹介 年間米国の金融・通信系スタートアップでエンジニア・マネー ジャ・ディレクターをしていました。 年から開発は 。ミッションクリティカルシステ ムにも使用しました。 昨年 の開発に特化した、株式会社シグニファ イアを設立。
紹介したいこと 紹介したいこと コードと デザインの乖離を無くし、メンテナンスコストを最 小に抑える の動的言語を活用したクイック・ターンアラウンドな開 発サイクル の活用例 質問・ディスカッションは で!
の文法解説 の詳細な使い方 の詳細
って って 型がないから心配 で静的型付き言語とは違ったアプローチでエラー チェック 起動が遅くて 駆動開発 によるホットリロー ディング カッコが多くて読み書きしづらそう
モードを使えばカッコを気にせずコーディングでき る!
フレームワーク フレームワーク ビルドツール 対話開発環境 サーバ抽象化フレームワーク 上で動作するルーティングライブラリ 上で 用の機能を追加したライ ブラリ
フレームワーク フレームワーク を定義する スペックに準拠し、設計、 ドキュメントなどをサポートするツール群 データ構造を定義し、バリデーションなどを行うラ イブラリ に や ス
キーマ、 サポート機能を付加するライブラリ サーバーを起動することなく 上のロジックをテスト することができるライブラリ
プロジェクトの生成と設定 プロジェクトの生成と設定 は をサポート、 はまだ 依存だが で 対応予定) lein new
compojure-api-with-spec
None
(defproject compojure-api-with-spec "0.1.0-SNAPSHOT" :description "compojure-api v2 and clojure.spec demo" :url
"https://github.com/k2n/compojure-api-with-spec" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[clj-time "0.14.0"] [metosin/compojure-api "2.0.0-alpha7"] [metosin/spec-tools "0.3.2"] [org.clojure/clojure "1.9.0-beta1"]] :ring {:handler compojure-api-with-spec.handler/app :async? true :nrepl {:start? true}} :uberjar-name "server.jar" :profiles {:dev {:dependencies [[peridot "0.5.0"]] :plugins [[lein-ring "0.12.0"] [com.jakemccrary/lein-test-refresh "0.21.1"]] :global-vars {*warn-on-reflection* true}}})
None
(ns compojure-api-with-spec.handler (:require [compojure.api.sweet :refer [api]] [compojure-api-with-spec [spec-coercion-routes :refer [spec-coercion-routes]]
[spec-validation-routes :refer [spec-validation-routes]]])) (def app (api {:swagger {:ui "/" :spec "/swagger.json" :data {:info {:title "Clojureでコード・ファーストなSwagger駆動REST API"} :tags [{:name "validation" :description "clojure.specによるバリデーション"} {:name "coercion" :description "clojure.specでコアーション"}]}}} spec-validation-routes spec-coercion-routes))
None
(ns compojure-api-with-spec.spec-validation-routes (:require [compojure.api.sweet :refer [context GET POST]] [ring.util.http-response :refer
[ok]] [clojure.spec.alpha :as s] [spec-tools.spec :as spec])) (def email-regex #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$") (def max-age 140) (s/def ::greeting (assoc spec/string? :description "このように注釈を定義することができる")) (s/def ::comment (assoc spec/string? :description "年齢の偶奇数を判定します")) (s/def ::response (s/keys :req-un [::greeting ::comment])) (s/def ::email (s/and spec/string? #(re-matches email-regex %))) (s/def ::age (s/and spec/int? #(> max-age %) #((complement neg?) %))) (defn validation-handler [email-address current-age] {:pre [(s/valid? ::email email-address) (s/valid? ::age current-age)] :post [(s/valid? ::response %)]} {:greeting (str email-address "を登録しました!") :comment (if (even? current-age) "あなたの年齢は偶数です"
None
(ns compojure-api-with-spec.spec-coercion-routes (:require [compojure.api.sweet :refer [context GET POST]] [compojure.api.coercion.spec :as
spec-coercion] [ring.util.http-response :refer [ok]] [clojure.spec.alpha :as s] [spec-tools.conform :as conform] [spec-tools.core :as st] [spec-tools.spec :as spec])) (s/def ::name spec/string?) (s/def ::amount (assoc spec/bigdec? :json-schema/type "string" :description "整数または小数を文字列として入力")) (s/def ::amount-type spec/string?) (defn string->bigdec [_ x] (cond (bigdec? x) x (string? x) (try (java.math.BigDecimal. x) (catch NumberFormatException e ::s/invalid)) :else ::s/invalid)) (def string-conforming (st/type-conforming
None
(ns compojure-api-with-spec.spec-routes-test (:require [clojure.test :refer :all] [clojure.edn :as edn] [cheshire.core
:as json] [compojure-api-with-spec.handler :refer [app]] [peridot.core :refer :all])) (deftest spec-routes-test (testing "validation" (testing "get" (testing "valid email address" (is (= 200 (-> (session app) (request "/
[email protected]
") :response :status)))) (testing "email address without domain" (is (= 400 (-> (session app) (request "/validation?email-address=foo") :response :status)))) (testing "email address without TLD" (is (= 400 (-> (session app) (request "/validation?email-address=foo@example") :response :status)))) (testing "email address with 1 character TLD, which is invalid."
終わりに 終わりに 今回の例はマクロを多用した 的な使われ方。通常はこれほど マジカルではない。 と はまだα版 の統合 への適用 を導入したくなったらお声がけください!コンサル・開
発承ります。