Web server and DB integration(1)Setting up a server in Clojure

Artificial Intelligence Technology   Semantic Web Technology   Search Technology     DataBase Technology   Ontology Technology   Digital Transformation Technology   User Interface and DataVisualization   Workflow & ServicesProgramming  Clojure

Previously, the quickest way to use the results of machine learning is to submit the data to a database or search engine. The client UI is visualized using node, react, or D3.js, and the server side is connected to the database or search engine via REST.

In this article, I’d like to talk about building a server-side system using Node and EXPRESS, but I’ll introduce a system using Clojure for building a slightly more complex business logic.

There are many ways to build a server (web) application with Clojure, but I will use “Ring”, “compojure”, and “clj-http” as relatively popular ones.

First, let’s look at Ring. Ring is a standard interface between web servers and web applications or frameworks, similar to Rack in Ruby or WSGI in Python. There are four components in Ring (handler, middleware, request map, response map), and the role of the handler is to receive the request map from the client and return the response map, while the middleware supplements the simple handler functions. The simplest handler looks like this

(defn handler [req]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body (:remote-addr req)})

A function called Handler is defined (defn), which receives an argument (input) called req, and defines the response data to be sent.

To begin with, communication on the Internet is done by sending and receiving communication packets according to the procedures defined by TCP (Transmission Control Protocol) and IP (Internet Protocol). TCP/IP is a means to transmit data without error. While TCP/IP is a means to send a mass of data without error, HTTP is a request message from the client to the server, telling the server “what” and “why” it wants something, and the server sends back a response message. In this case, the URL is the “what” and the method is the “why”.

Ring’s request and response maps are represented by Clojure’s data structure, edn((extensible data notation)), as shown in the code example above.

The actual keys that appear in Ring’s request map are as follows

:server-port リクエストをハンドルしたポート番号
:server-name 解決されたサーバー名もしくは IP アドレス
:remote-addr クライアントか最後にリクエストを投げたプロキシの IP アドレス
:uri リクエスト URI (ドメイン名以下のフルパス)
:query-string もしあればクエリ文字列
:scheme トランスポートプロトコル :http または :https
:request-method HTTP リクエストメソッド :get, :head, :options, :put, :post, :delete のいずれか
:headers ヘッダーの文字列を小文字化したキーを持つマップ
:body もしあればリクエストボディのための InputStream

The response map created by the handler has the following three keys

:status HTTP ステータス
:headers クライアントへと返す HTTP ヘッダー
:body レスポンスボディ

The key statuses of the response map are the same as those defined in the HTTP RFC, such as 200, 404, etc., which are commonly seen in web browsers.

In the case of database integration, which is the initial goal, the request map will reflect the settings of the database side, and the response map will be configured according to the information defined in the API.

Now, let’s start up a concrete server. First, add the ring library to the project.clj file.

:dependencies [[org.clojure/clojure "1.10.1"]
                           [ring "1.8.2"]]

Next, make the core.clj of src as follows.

(ns my-app.core
  (:require [ring.adapter.jetty :as server]))

(defonce server (atom nil))  ;;  (1)

(defn handler [req]                  ;;(2)
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body "Hello, world"})

(defn start-server []                 ;;(3)
  (when-not @server
    (reset! server (server/run-jetty handler {:port 3000 :join? false}))))

(defn stop-server []               ::(4)
  (when @server
    (.stop @server)
    (reset! server nil)))

(defn restart-server []           ;;(5)
  (when @server
    (stop-server)
    (start-server)))

(1) is the creation of the server instance. (2) sets the handler function, (3) starts the server, (4) stops the server and (5) restarts it. Open the above file in spacemacs, press “SPC”, “m”, “s”, and “i” to start the repl server, and press “CTRL”, “c”, and “e” at the same time after each function to evaluate it. If you type “localhost:3000/”, you will see “Hello world”. You can also check the response by typing “curl -i localhost:3000/” in a terminal.

In this article, I described how to set up a server using Clojure’s ring. In the next article, I would like to describe the routing using compojure and clj-http.

コメント

タイトルとURLをコピーしました