FreeLang v9 프레임워크

FreeLang v9는 실무 개발을 위한 3가지 주요 프레임워크를 제공합니다.


1. FLNext — 웹 프레임워크

Express 의존성 없이 순수 v9로 작성된 웹 프레임워크.

기본 사용법

(import flnext)

[APP
 :name "my-app"
 :port 3000
 :database {:url "sqlite:app.db"}
 :routes [
  [GET "/" (fn [req] {:body "Hello World"})]
  [GET "/users/:id" (fn [req]
    (user-service/get-user (:id (:params req))))]
  [POST "/users" (fn [req]
    (user-service/create-user (:body req)))]
  [PUT "/users/:id" (fn [req]
    (user-service/update-user (:id (:params req)) (:body req)))]
  [DELETE "/users/:id" (fn [req]
    (user-service/delete-user (:id (:params req))))]
 ]
 :middleware [
  auth-middleware
  logging-middleware
  cors-middleware
 ]]

ORM (Object-Relational Mapping)

[MODEL User
 :table "users"
 :fields [
  {:name "id" :type "INTEGER" :primary-key true}
  {:name "email" :type "TEXT" :unique true}
  {:name "name" :type "TEXT"}
  {:name "created-at" :type "TIMESTAMP"}
 ]
 :indexes [
  {:name "email_idx" :columns ["email"]}
 ]]

; CRUD 연산
(user/create {:email "user@example.com" :name "John"})
(user/find-by-id 1)
(user/find-by :email "user@example.com")
(user/update 1 {:name "Jane"})
(user/delete 1)

스키마 검증

[SCHEMA UserSchema
 :fields {
  :email {:type "email" :required true}
  :password {:type "string" :min 8 :max 128 :required true}
  :name {:type "string" :min 1 :max 100 :required true}
  :age {:type "integer" :min 0 :max 150}
 }]

; 검증
(if (schema-valid? UserSchema user-data)
  (print "유효한 데이터")
  (print "검증 실패:" (schema-errors UserSchema user-data)))

미들웨어 체인

[MIDDLEWARE auth-check
 :condition (fn [req] (has? (:headers req) "authorization"))
 :handler (fn [req]
   (assoc req :user (validate-token (get-token (:headers req)))))
 :on-fail (fn [req]
   {:status 401 :body "Unauthorized"})]

[MIDDLEWARE rate-limit
 :condition (fn [req] (< (get-request-count (:ip req)) 100))
 :handler (fn [req]
   (increment-request-count (:ip req))
   req)
 :on-fail (fn [req]
   {:status 429 :body "Too Many Requests"})]

2. v9-data — 데이터 분석

테이블, 통계, 시각화를 통한 데이터 처리:

테이블 조작

(import v9-data)

; CSV 로드
(let [data (table/load-csv "sales.csv")]
  (-> data
      (table/filter (fn [row] (> (:amount row) 1000)))
      (table/sort :date :desc)
      (table/group-by :region)))

; 테이블 연산
(table/select data ["name" "email" "amount"])
(table/aggregate data "amount" :sum)
(table/join data1 data2 :on "user_id")

통계 분석

(let [scores [85 90 75 92 88 78 95]]
  {:mean (stats/mean scores)
   :median (stats/median scores)
   :stddev (stats/stddev scores)
   :min (stats/min scores)
   :max (stats/max scores)
   :quartiles (stats/percentiles scores [0.25 0.5 0.75])})

; 상관 분석
(let [x [1 2 3 4 5]
      y [2 4 6 8 10]]
  (stats/correlation x y))  ; → 1.0 (완벽한 양의 상관)

; 정규화
(stats/normalize [0 50 100])  ; → [0.0 0.5 1.0]

시각화

; 히스토그램
(plot/histogram [10 20 15 25 30 18 22]
 :title "Distribution"
 :bins 5)

; 막대 그래프
(plot/bar ["A" "B" "C" "D"]
 [100 150 200 180]
 :title "Sales by Region")

; 선 그래프
(plot/line [1 2 3 4 5]
 [10 15 13 17 20]
 :title "Trend")

; 산점도
(plot/scatter [1 2 3 4 5]
 [10 15 13 17 20])

; 파일로 저장
(plot/save chart "output.svg")

3. 마이크로서비스 프레임워크

분산 시스템 구축:

서비스 정의

[SERVICE user-service
 :port 8001
 :database {:url "sqlite:users.db"}
 :routes [
  [GET "/users/:id" get-user]
  [POST "/users" create-user]
  [DELETE "/users/:id" delete-user]
 ]]

[SERVICE order-service
 :port 8002
 :database {:url "sqlite:orders.db"}
 :routes [
  [GET "/orders/:id" get-order]
  [POST "/orders" create-order]
 ]]

메시지 큐

; 큐 생성
(queue/create "events" :type "file")

; 이벤트 발행
(queue/publish "events" "user.created"
 {:user-id 123 :email "user@example.com"})

; 이벤트 구독
(queue/subscribe "events" "user.created"
 (fn [message]
  (println "New user created:" (:user-id message))))

; 구독 취소
(queue/unsubscribe subscription-id)

Circuit Breaker (장애 격리)

[CIRCUIT-BREAKER external-api
 :threshold 5        ; 5번 실패 시 OPEN
 :timeout 30000      ; 30초 후 HALF-OPEN 시도
 :fallback (fn []
  {:status "error" :message "Service unavailable"})]

; Circuit breaker를 통한 호출
(circuit/call "external-api"
 (fn []
  (http/get "https://external-api.com/data")))

모니터링

; 메트릭 기록
(observe/metric "requests" 1 :type "counter")
(observe/metric "latency" 125 :type "histogram")
(observe/metric "active-connections" 42 :type "gauge")

; 에러 카운팅
(observe/count-errors "database")
(observe/count-errors "external-api")

; 로깅
(observe/log "info" "User login successful" {:user-id 123})
(observe/log "error" "Database connection failed" {:error "timeout"})

; 메트릭 리포트
(observe/report)
; → {:metrics {...} :services [...] :health {...}}

; Prometheus 형식 출력
(observe/prometheus)

통합 예제: SaaS 플랫폼

(import flnext)
(import v9-data)

; 데이터 모델
[MODEL User
 :table "users"
 :fields [
  {:name "id" :type "INTEGER" :primary-key true}
  {:name "email" :type "TEXT" :unique true}
  {:name "created-at" :type "TIMESTAMP"}
 ]]

[MODEL Order
 :table "orders"
 :fields [
  {:name "id" :type "INTEGER" :primary-key true}
  {:name "user-id" :type "INTEGER" :foreign-key "users.id"}
  {:name "amount" :type "DECIMAL"}
  {:name "status" :type "TEXT"}
 ]]

; 검증 스키마
[SCHEMA CreateOrderSchema
 :fields {
  :user-id {:type "integer" :required true}
  :amount {:type "decimal" :required true :min 0.01}
  :items {:type "array" :required true}
 }]

; 미들웨어
[MIDDLEWARE request-logging
 :handler (fn [req]
  (observe/log "info" "Request" {:method (:method req) :path (:path req)})
  req)]

; 라우트
(defn create-order [req]
  (let [data (:body req)]
    (if (schema-valid? CreateOrderSchema data)
      (do
        (order/create data)
        {:status 201 :body {:success true}})
      {:status 400 :body {:error (schema-errors CreateOrderSchema data)}})))

; 앱 정의
[APP sales-platform
 :port 3000
 :database {:url "sqlite:app.db"}
 :middleware [request-logging]
 :routes [
  [POST "/orders" create-order]
  [GET "/analytics" analytics-dashboard]
  [GET "/health" health-check]
 ]]

다음 단계