Scalaで最も単純なREST Webサービスを作成します

Node.jsで記述されたサイトがありますが、Node.jsが意図していない何かを行う必要がある場合があります。たとえば、数学的計算を行う場合などです。

この例では、パスワードハッシュを計算します。

この作業を(計算に適した)関数型プログラミング言語で記述された「バックエンド」に任せましょう。 たとえば、 Scalaで 。 機能的には、次のようになります。Node.jsはハッシュのためのハッシュリクエストをバックエンドに送信し、バックエンドはJson形式で計算されたハッシュを考えて考えて送信します。 通常のHTTP要求/応答、複雑なことは何もありません。

ツールキット


「フレームワーク」のセットを選択するという点で、問題を解決するための多くのアプローチがあります。

Sinatraフレームワークを喜んで使用して、(「Rails」ではなく)Rubyで少し書きました。 Node.jsでは、 Expressという名前のSinatraクローンを使用します。 Scalaは対応するクローンScalatraも作成したことが判明しました。 それを使用します。

Scalaの人気のあるレスト「フレームワーク」


また、Scala用のいくつかの認識された軽量Restフレームワークもあります。



これらの「フレームワーク」は、コメントの中でユーザーbtdによって提案されました。 しかし、私はそれらのどれも好きではありませんでした-Scala言語自体のように、すべてが高度すぎます。 私はもっ​​と簡単なものが好きです...これは、ここで私がScalaではなく、Scala構文のJavaで書いていることをmanyする人が多い理由の1つです。 私は議論せず、Javascriptを好みます。Scalaは、「関数はオブジェクトです」というアプローチを与えてくれます。

この全体を起動する方法


Zen Buddhistの場合、2つのファイルで十分“javac -d classes *.java; scalac -classpath […] -d classes *.scala” という形式のbuild.sh “javac -d classes *.java; scalac -classpath […] -d classes *.scala” “javac -d classes *.java; scalac -classpath […] -d classes *.scala”および“scala -classpath […] -D=8090 Main” 形式のrun.sh

ただし、ファイル名マスクと1行の長いクラスパスで混乱しないように、「コレクター」を使用することをお勧めします。正しいコレクター(Mavenではない)は、シェルよりもはるかに自由(および読みやすさ)を提供します。 彼はあなたに使用されているすべてのライブラリをダウンロードし、 クラスパスに各Jar'nikを名前で追加します(手動で行う必要はありません)。

若い(現在バージョン1.0について)および開発中のGradleプロジェクトを取り上げます。Mavenよりも古き良きAntを思い起こさせます。開発者をタイトなフレームに閉じ込めることはありませんが、逆に、完全な創造性の自由、そして適切なGroovy言語 (Javaの世界でのRubyクローン)でさえも。

設置


JDKを入れました。 チェック: java -version

* JDKフォルダーでJAVA_HOMEシステム変数を設定し、PATHにbinを登録する必要がある場合もあります。

Scalaをダウンロードし、 binPATH書き込みます。 チェック: scala –version

Gradleをダウンロードし、 binPATH書き込みます。 チェック: gradle –v

プロジェクト



プロジェクト自体はgithubにあります。 ここでは、3つのメインファイルのコードを示します。

Gradleの組み立て手順-build.gradle

 //   Scala apply plugin: 'scala' ext.scala_version = '2.9.1' ext.jersey_version = '1.12' ext.description = 'Accessing various calculation tasks' //   —   - //   «compileJava»  «compileScala»,      task go(dependsOn: ['compileJava', 'compileScala'], type: JavaExec) { main = 'Main' classpath = sourceSets.main.runtimeClasspath standardInput = System.in systemProperty 'package', 'web' systemProperty 'port', '8090' } //    sourceSets { //  main { java { //      «sources» srcDir 'sources' } scala { //  Scala    «sources» srcDir 'sources' } } } //      «classes» sourceSets.main.output.classesDir = 'classes' //   dependencies { //     Scala  Gradle scalaTools group: 'org.scala-lang', name: 'scala-compiler', version: scala_version scalaTools group: 'org.scala-lang', name: 'scala-library', version: scala_version //  ,    compile group: 'org.scalatra', name: 'scalatra_2.9.1', version: '2.1.0.M1' runtime group: 'org.scalatra', name: 'scalatra_2.9.1', version: '2.1.0.M1' compile group: 'org.mortbay.jetty', name: 'jetty', version: '7.0.0.pre5' runtime group: 'org.mortbay.jetty', name: 'jetty', version: '7.0.0.pre5' compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1' //      jar-   «libraries», //        compile fileTree(dir: 'libraries', include: '*.jar') runtime fileTree(dir: 'libraries', include: '*.jar') } //     repositories { mavenCentral() } 


実際、REST Webサービスにより、 WhirlpoolまたはSHA-512 - Hasher.scalaでパスワードをハッシュできるようになりました。

 package web import hash.Whirlpool import hash.SHA class Hasher extends tools.WebService { def path = "/ѣ" get("/") { " : Whirlpool, SHA" } get("/Whirlpool/:what") { val  = params("what") json("" -> , "ѣ" -> Whirlpool.hash()) } get("/SHA/:what") { val  = params("what") json("" -> , "ѣ" -> SHA.hash()) } } 


そして、私が書いたWebサーバーランチャー(build.gradleで指定された「パッケージ」パッケージからすべてのWebサービスを起動します) -Main.scala

 import org.mortbay.jetty.Server import org.mortbay.jetty.servlet.{Context, ServletHolder} import tools._ object Main extends App { //  Jetty val server = new Server(System.getProperty("port").toInt) val root = new Context(server, "/", Context.SESSIONS) //      Rest - val package_name : String = System.getProperty("package") //   ScalatraServlet    ( ) ""   . //    "path"  . for (handler <- PackageScanner.getClasses(package_name) if classOf[org.scalatra.ScalatraServlet].isAssignableFrom(handler)) { //      val servlet = handler.newInstance().asInstanceOf[javax.servlet.Servlet] //    ""  try { //     path() val path = handler.getMethod("path").invoke(servlet).toString // ""      Jetty root.addServlet(new ServletHolder(servlet), path + "/*") println(handler.getPackage().getName() + "." + handler.getName() + " is mapped to " + path) } catch { //    path()   case error: NoSuchMethodException => throw new RuntimeException("Method path() not found in class " + handler.getPackage().getName() + "." + handler.getName()) } } //  Jetty server.start() server.join() } 


打ち上げ


アーカイブをダウンロードして解凍し、フォルダーに移動してgradle goコマンドを実行します。 成功すると、コンソールにWebサーバーの起動が表示されます。

グラドルゴー
 :compileJava
 :compileScala
 :processResourcesの最新情報
 :クラス
 :行く
 SLF4J:クラス「org.slf4j.impl.StaticLoggerBinder」のロードに失敗しました。
 SLF4J:デフォルトの無操作(NOP)ロガー実装
 SLF4J:詳細については、http://www.slf4j.org/codes.html#StaticLoggerBinderを参照してください
 >建物>:行く


確認する


あいさつ
SHA-512アルゴリズムを使用してパスワードをハッシュする
Whirlpoolアルゴリズムを使用してパスワードをハッシュする

何もする必要がない(または面白い)場合は、もっと読むことができます


スカラトラ
Gradleでアセンブリを記述する方法
シンプルなジャージーRESTサービス
ロシア語のGradleについて
Scalaとは何で、何が便利ですか
フィルタなし-Scala用の軽量RESTフレームワーク
SprayはScalaの高度なRESTフレームワークです
Blue Eyesは、Scala用の高度なRESTフレームワークでもあります。

Source: https://habr.com/ru/post/J143603/


All Articles