無料でPHP使ってWebAPIをつくってみた

# はじめに
以前つくった[文字列→塩基配列の相互変換ツールをつくってみた(アプリ版)](https://qiita.com/am10/items/3ecac20451c82133e900)のWeb版（PHP）が[これ](https://qiita.com/am10/items/2516fa04def815195ffe)により不要になってしまいました:scream:

せっかく作ったPHP版も何かに使えないかと思いAPI化してみました:clap:

＊注意 httpです:see_no_evil:

# 成果物
## ドキュメント
BluePrintでAPIドキュメントみたいなのつくってみましたので詳細はこれを見てください:bow:

[http://adventam10.php.xdomain.jp/dna/api/](http://adventam10.php.xdomain.jp/dna/api/)

## ソース
下記の dna-converter.php です。

[https://github.com/adventam10/DNAConverter-web/tree/master/api](https://github.com/adventam10/DNAConverter-web/tree/master/api)

# API化
[PHPで簡単なWebAPIを実装してみる](https://note.com/kazztech/n/ndb3a5468f299)を参考に実装！！

こんな感じで実装して下記のように XFREE にアップ！！！

[無料でできるPHPのWEBサイト公開（テスト用）](https://qiita.com/am10/items/a3b6a5239905da3ec18f)

```php
<?php
header('Content-Type: text/html; charset=UTF-8');

$json_string = file_get_contents('php://input');
$json = json_decode($json_string, true);
$resultCode = checkResultCode($json);
if($resultCode === 0) {
    $arr["resultCode"] = $resultCode;
    $arr["convertedText"] = convert($json["text"], $json["mode"]);
} else {
    $arr["resultCode"] = $resultCode;
}

print json_encode($arr, JSON_PRETTY_PRINT);
```

swift で確認してみる

```swift
let urlString = "http://adventam10.php.xdomain.jp/dna/api/dna-converter.php"
var request = URLRequest(url: URL(string: urlString)!)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = try? JSONEncoder().encode(Request(mode: 0, text: "あいうえお"))
let task = URLSession.shared.dataTask(with: request) { (data, _, error) in
  let response = try? JSONDecoder().decode(Response.self, from: data!)
  print(response)
}
task.resume()

struct Request: Codable {
    let mode: Int
    let text: String
}

struct Response: Codable {
    let resultCode: Int
    let convertedText: String
}
```

ちゃんと以下のように取得できていました:clap:

```swift
Optional(Test.Response(resultCode: 0, convertedText: "GCAGCAATCAACGCAGCAATCATAGCAGCAATCATCGCAGCAATCACAGCAGCAATCACC"))
```

## ハマったとこ
[POSTMAN](https://www.postman.com/) を使って確認していたのですが下記のようにリクエストをしていると mode が数値ではなく文字列になってしまいハマりました。

<img width="500" alt="postman_1" src="https://user-images.githubusercontent.com/34936885/74592065-f4101a80-5060-11ea-84c8-005363195df3.png">

その時のPHPの実装が下記

```php
$resultCode = checkResultCode($_POST);
function checkResultCode($param) {
  if (isset($param["mode"])) {
    $mode = $param["mode"];
    if ($mode === 0 || $mode === 1) { // 文字列なのでここでアウト
      if (!empty($param['text'])) {
        $text = $param['text'];
        if ($mode === 0) {
          return 0;
        } else {
          if (isInvalidDNA($text)) {
            return 4;
          } else {
            return 0;
          }
        }
      } else {
        return 3;
      }
    } else {
      return 2;
    }
  } else {
    return 1;
  }
}
```

POSTMAN で下記のように JSON を設定すると数値が送れるらしいと聞いたので修正。

<img width="500" alt="postman_2" src="https://user-images.githubusercontent.com/34936885/74592067-fa05fb80-5060-11ea-8a44-b5320c0f8d66.png">

が、しかし、PHP が `$_POST` だったので値を受け取れず:scream:

どうやら `$_POST` では JSON を受け取れない模様。

参考：[JSON形式でPOSTされたデータの受信方法](http://www.initialsite.com/g07/14794)

下記のように PHP を修正。

```php
$json_string = file_get_contents('php://input');
$json = json_decode($json_string, true); // 第2引数にtrueを設定しないとダメらしい
$resultCode = checkResultCode($json);
function checkResultCode($param) {
  if (isset($param["mode"])) {
    $mode = $param["mode"];
    if ($mode === 0 || $mode === 1) {
      if (!empty($param['text'])) {
        $text = $param['text'];
        if ($mode === 0) {
          return 0;
        } else {
          if (isInvalidDNA($text)) {
            return 4;
          } else {
            return 0;
          }
        }
      } else {
        return 3;
      }
    } else {
      return 2;
    }
  } else {
    return 1;
  }
}
```

無事数値を取得できました:clap:

# ドキュメント作成
せっかくなんで API Blueprint でドキュメントを作成してみました。

参考：[API BlueprintでWeb APIのドキュメントを生成する](https://qiita.com/yagays/items/8e16a27b058f0ddef653)

## ハマったとこ
node.js を [https://nodejs.org/ja/](https://nodejs.org/ja/) ここから取得して入れていたので `npm install -g aglio` がパーミッションエラーになってしまいました:scream:

下記参考に設定を行い無事インストールできました:clap:

[npmでpermission deniedになった時の対処法[mac]](https://qiita.com/okohs/items/ced3c3de30af1035242d)

ドキュメントの書き方あんまわからなかったので下記参考にしながらそれっぽいものを書いてみました。

[API Blueprint を使って Web API の仕様書を書こう](https://blog.fenrir-inc.com/jp/2017/01/api-blueprint.html)

# さいごに
とりあえずこれで PHP で作成したものも無駄にならずにすみました:tada:

これでどこからでもDNA変換ができます！！！

（swift の POST がライブラリ使わずにやるのやり方忘れてて地味に苦労しました:speak_no_evil:）