目次
はじめに
最近、様々な言語で作られたツールを連携するのに、
JSONファイルを使っているのですが、
今回は、
そのJSONファイルを様々なプログラミング言語でやり取りするための
シンプルなJSONサーバ・JSONクライアントのコードを紹介したいと思います。
今回のサンプルコードでは、
基本的にクライアントがJSONファイルをHTTP経由で送信し、
そのサーバがそのJSONファイルを元に、
JSONファイルを返信するという用途でサンプルコードを作成します。
紹介するコードはすべて下記のリポジトリで公開しています。
順次、対応言語も増やしていく予定です。
Python
Server
基本的にデフォルトモジュールのみを使って実現できます。
""" JSON Server with python author: Atsushi Sakai (@Atsushi_twi) """ from http.server import HTTPServer, SimpleHTTPRequestHandler from urllib.parse import parse_qs, urlparse import json from datetime import datetime import math class MyHandler(SimpleHTTPRequestHandler): def do_POST(self): # get request content_len = int(self.headers.get('content-length')) req = json.loads(self.rfile.read(content_len)) print("request") print(req) uri = self.path ret = parse_qs(urlparse(uri).query, keep_blank_values=True) res = {} res["title"] = "Python JSON server" res["time"] = datetime.now().strftime("%Y%m%d%H%M%S") res["PI"] = math.pi print("response") print(res) ret = json.dumps(res) body = bytes(ret, 'utf-8') self.send_response(200) self.send_header('Content-Type', 'application/json') self.send_header('Content-length', len(body)) self.end_headers() self.wfile.write(body) def main(): host = 'localhost' port = 8000 httpd = HTTPServer((host, port), MyHandler) print('serving at port', port) httpd.serve_forever() print(__file__ + " start!!") if __name__ == '__main__': main()
Client
こちらもデフォルトモジュールのrequestsを使いました。
""" JSON Client with python author: Atsushi Sakai (@Atsushi_twi) """ import requests import json def main(): headers = {"content-type": "application/json"} url = "http://localhost:8000" obj = {"Type": "python json client", 123: 123} json_data = json.dumps(obj) print("request:") print(json_data) response = requests.get(url, headers=headers, data=json_data) res = response.json() print("response:") print(res) if __name__ == '__main__': main()
Julia
Server
JSONサーバではHttpのServer用に
HttoServerモジュールと、
JSONパーサとして、JSONモジュールを
使用しています。
# # JSON Server with julia # # author: Atsushi Sakai # using HttpServer using JSON function response_json(req) println("json requested!!") # Parse input json jreq=JSON.parse(String(req.data)) println("request:") println(jreq) jres = Dict("title"=>"Julia JSON server", "PI" => pi) jres["time"] = Dates.format(Dates.now(), "yyyymmddHHMMSS") println("response:") println(jres) return JSON.json(jres) end function main() println(PROGRAM_FILE," start!!") http = HttpHandler() do req::Request, res::Response Response(response_json(req)) end server = Server(http) host = IPv4(127,0,0,1) # localhost port = 8000 run(server, host=host, port=port) println("serving at port", port) println(PROGRAM_FILE," Done!!") end main()
Client
クライアントでは、Requestsモジュールを
利用しています。
# # JSON client with Julia # # author: Atsushi Sakai # using Requests function main() req = Dict("Name" => "julia json request") println("request:") println(req) url = "http://localhost:8000" res = Requests.json(Requests.post(url; json = req)) println("response:") println(res) println(PROGRAM_FILE," Done!!") end main()
C++
C++はデフォルト機能として、
Http serverやJSONパーサーの機能が無いので、
下記の2つのヘッダーライブラリを使いました。
Client
// // Json http client in C++ // // Author: Atsushi Sakai // #include <iostream> #include "../cpp-httplib/httplib.h" #include "../json/single_include/nlohmann/json.hpp" using namespace std; using json = nlohmann::json; int main(void){ cout<<"c++ Json client start !!"<<endl; // Create request json map<string, string> c_map { {"Name", "request_from_cpp_client"}, {"Test", "test"} }; json j_map(c_map); string sjson = j_map.dump(); cout << "Request:" << endl; cout << sjson << endl; httplib::Client cli("localhost", 8000); auto res = cli.Post("/", sjson, "application/json"); if (res && res->status == 200) { cout << "Response:" << endl; auto jres = json::parse(res->body); for (json::iterator it = jres.begin(); it != jres.end(); ++it) { cout << it.key() << " : " << it.value() << endl; } } }
Server
// // Json http server in C++ // // Author: Atsushi Sakai // #include <iostream> #include "../cpp-httplib/httplib.h" #include "../json/single_include/nlohmann/json.hpp" using namespace std; using json = nlohmann::json; int main(void){ cout<<"c++ Json server start !!"<<endl; httplib::Server svr; svr.Post("/", [](const httplib::Request& req, httplib::Response& res) { cout<<"request"<<endl; cout<<req.body<<endl; map<string, string> c_map { {"Name", "response_from_cpp_server"}, {"Test", "test2"} }; json j_map(c_map); res.set_content(j_map.dump(), "application/json"); }); svr.listen("localhost", 8000); }
curl
Client
curlをシンプルなJSONクライアントとして使うことができます。
RequestのJSONを引数に入れる場合は下記のようにjsonリクエストを送信できます。
curl -X GET -H "Content-Type: application/json" -d '{"Name":"json request"}' localhost:8000
-XでHTTPのメソッドを指定し、
-Hでアプリケーションタイプをjsonとします。
そして、-dでリクエストのJSONを指定し、
最後にリクエスト先のURLとポートを指定する形です。
サーバからのレスポンスは、標準出力に表示されます。
ファイルとして保存されたjsonファイルを使う場合は、
$ curl -X POST -H "Content-Type: application/json" -d @request.json localhost:8000
のように@の後にjsonファイル名を入れればOKです。
参考資料
MyEnigma Supporters
もしこの記事が参考になり、
ブログをサポートしたいと思われた方は、
こちらからよろしくお願いします。