CodeIgniter3 JSONを返すAPIサーバーとして使用する
PHPフレームワークのCodeIgniterhttp://www.codeigniter.com/
JSON形式な文字列を返すAPIサーバーとして使用してみます。
簡単なサンプル
ドキュメントを見ると、outputクラスを用いたサンプルがあります。
https://www.codeigniter.com/userguide3/libraries/output.html
簡単なコントローラークラスを作成して試してみます。
・application/controllers/Api.php
- <?php
- class Api extends CI_Controller {
- public function index() {
- $this->output
- ->set_content_type('application/json')
- ->set_output(json_encode(array('foo' => 'bar')));
- }
- }
これをPythonから呼び出して使ってみます。
- # -*- coding:utf-8 -*-
- import json
- import urllib2
- url = 'http://192.168.1.103:8080/api'
- response = urllib2.urlopen(url)
- # 戻り値を解析
- body = response.read()
- response.close()
- data = json.loads(body)
- print(data['foo'])
うまく動いてくれたようです。
$ python api_test.py
bar
郵便番号検索サンプル
mariadbに郵便番号データを登録して検索してみます。
テーブルレイアウトは以下のとおり。
create table zip (
zip_code char(7) not null primary key,
address varchar(200)
);
データはこちらから全国版を取得しました。
http://www.post.japanpost.jp/zipcode/dl/kogaki-zip.html
重複しないよう、適当に加工して登録します。
- # -*- coding:utf-8 *-
- import codecs
- import MySQLdb
- def execute(line, cur, zips):
- data = [s.strip('"') for s in line.split(u',')]
- zip_code = data[2]
- if zip_code in zips:
- return
- address = data[6] + data[7] + data[8]
- cur.execute(u"insert into zip(zip_code, address) values (%s, %s)", [zip_code, address])
- zips.add(zip_code)
- con = MySQLdb.connect(
- host='localhost',
- db='sample',
- user='root',
- passwd='P@ssw0rd',
- charset='utf8')
- cur = con.cursor()
- zips = set()
- with codecs.open('KEN_ALL.CSV', 'r', 'ms932') as f:
- for line in f:
- execute(line.strip(), cur, zips)
- con.commit()
- cur.close()
- con.close()
これで下準備完了です。
CodeIgniterのconfig/database.phpを微調整。
- $active_group = 'default';
- $query_builder = TRUE;
- $db['default'] = array(
- 'dsn' => '',
- 'hostname' => 'localhost',
- 'username' => 'root',
- 'password' => 'P@ssw0rd',
- 'database' => 'sample',
- 'dbdriver' => 'mysqli',
- 'dbprefix' => '',
- 'pconnect' => FALSE,
- 'db_debug' => (ENVIRONMENT !== 'production'),
- 'cache_on' => FALSE,
- 'cachedir' => '',
- 'char_set' => 'utf8',
- 'dbcollat' => 'utf8_general_ci',
- 'swap_pre' => '',
- 'encrypt' => FALSE,
- 'compress' => FALSE,
- 'stricton' => FALSE,
- 'failover' => array(),
- 'save_queries' => TRUE
- );
検索したい郵便番号を引数として受け取り、検索結果を返すControllerはこうなりました。
- <?php
- class Api extends CI_Controller {
- // 郵便番号検索
- public function zip($zip_code) {
- $this->load->database();
- $this->db->select('address');
- $this->db->from('zip');
- $this->db->where('zip_code', $zip_code);
- $rows = $this->db->get()->result_array();
- // 検索結果をそのまま返す
- $this->output
- ->set_content_type('application/json')
- ->set_output(json_encode($rows));
- }
- }
Pythonから使ってみます。
- # -*- coding:utf-8 -*-
- import json
- import urllib2
- url = 'http://192.168.1.103:8080/api/zip/0690364'
- response = urllib2.urlopen(url)
- # 戻り値を解析
- body = response.read()
- response.close()
- data = json.loads(body)
- for row in data:
- print(row['address'])
動いてくれました。
$ python api_test.py
北海道岩見沢市上幌向南三条
リクエストボディーを引数として使用する
リクエストボディにJSONな文字列を設定。
その値をAPIの引数として使用するよう構成します。
こんな場合は、raw_input_streamが使えます。
https://www.codeigniter.com/userguide3/libraries/input.html
- <?php
- class Api extends CI_Controller {
- // 郵便番号検索
- public function zip() {
- // クライアントからの値を復元
- $query = json_decode($this->input->raw_input_stream);
- $this->load->database();
- $this->db->select('address');
- $this->db->from('zip');
- $this->db->where('zip_code', $query->zip_code);
- $rows = $this->db->get()->result_array();
- // 検索結果をそのまま返す
- $this->output
- ->set_content_type('application/json')
- ->set_output(json_encode($rows));
- }
- }
テスト用のサンプルはこのようになりました。
- # -*- coding:utf-8 -*-
- import json
- import urllib2
- url = 'http://192.168.1.103:8080/api/zip'
- values = {'zip_code':'0690364'}
- send_data = json.dumps(values)
- req = urllib2.Request(url, send_data)
- response = urllib2.urlopen(req)
- # 戻り値を解析
- body = response.read()
- response.close()
- data = json.loads(body)
- print data[0]['address']
ちゃんと検索結果が取得できています。
$ python api_test.py
北海道岩見沢市上幌向南三条
画像データを送信
リクエストヘッダーにファイル名。
リクエストボディーに画像データを入れて送信。
サーバー側で復元してみます。
まずサーバー側。
- <?php
- class Api extends CI_Controller {
- // 画像アップロード
- public function upload() {
- // クライアントからの値を復元
- // ファイル名
- $file_name = $this->input->get_request_header('File-name');
- // 画像データ
- $image = $this->input->raw_input_stream;
- // 指定されたファイル名で保存
- file_put_contents(FCPATH.$file_name, $image);
- // 保存結果を返信
- $this->output
- ->set_content_type('application/json')
- ->set_output(json_encode(['result' => 'ok']));
- }
- }
ファイル送信のサンプルはこのようになりました。
- # -*- coding:utf-8 -*-
- import json
- import urllib2
- url = 'http://192.168.1.103:8080/api/upload'
- headers = { 'File-name' : 'sample.jpg' }
- with open('cc2.jpg', 'rb') as f:
- image = f.read()
- req = urllib2.Request(url, image, headers)
- response = urllib2.urlopen(req)
- # 戻り値を解析
- body = response.read()
- response.close()
- data = json.loads(body)
- print data
ちゃんとサーバー側に画像ファイルが復元できました。
- 関連記事
コメント