LoginSignup
15
13

More than 3 years have passed since last update.

【API】郵便番号検索APIを使ってみた

Last updated at Posted at 2020-05-16

APIを使用したアプリを作ってみる

背景

  • APIを使用したアプリケーションが増えてきている
  • APIを使用する、作るエンジニアの仕事も増えている
  • APIを扱う技術の需要が増えそう

目次

0.環境確認

  • OS: Windows10 home
  • IDE : Eclipse(Photon 4.8)
  • ビルドツール : Gradle
  • サーバーサイド言語 : Java(1.8)
  • フレームワーク : SpringBoot(2.2.7)
  • JavaScript ライブラリ : jQuery(3.3.1)
  • テンプレートエンジン : thymeleaf

1.APIの確認

  • 以下のサイトからAPIの使用を確認します。
    https://zip-cloud.appspot.com/doc/api

  • 仕様を確認します。

    パラメータ名 項目名 必須 備考
    zipcode 郵便番号 7桁の数字。ハイフン付きでも可。完全一致検索。
    callback コールバック関数名 - JSONPとして出力する際のコールバック関数名。UTF-8でURLエンコードした文字列。
    limit 最大件数 - 同一の郵便番号で複数件のデータが存在する場合に返される件数の上限値(数字) ※デフォルト:20
    • レスポンスパラメータ
    フィールド名 項目名 備考
    status ステータス 正常時は 200、エラー発生時にはエラーコードが返される
    message メッセージ エラー発生時に、エラーの内容が返される。
    results zipcode(郵便番号)
    prefcode(都道府県コード)
    address1(都道府県名)
    address2(市区町村名)
    address3(町域名)
    kana1(都道府県名カナ)
    kana2 (市区町村名カナ)
    kana3(町域名カナ)
    複数の場合、配列となる
    • (例)郵便番号「7830060」で検索する場合
      • リクエストURL https://zip-cloud.appspot.com/api/search?zipcode=7830060
      • レスポンス

        { "message": null, "results": [ { "address1": "北海道", "address2": "美唄市", "address3": "上美唄町協和", "kana1": "ホッカイドウ", "kana2": "ビバイシ", "kana3": "カミビバイチョウキョウワ", "prefcode": "1", "zipcode": "0790177" }, { "address1": "北海道", "address2": "美唄市", "address3": "上美唄町南", "kana1": "ホッカイドウ", "kana2": "ビバイシ", "kana3": "カミビバイチョウミナミ", "prefcode": "1", "zipcode": "0790177" } ], "status": 200 }

2.プロジェクトの作成

別の記事で詳細に紹介しているので、そちらを参照ください。
GradleのSpringBootプロジェクトを作成する

3.バックエンドの実装

  • build.gradle
build.gradle
//中略
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    compile("com.fasterxml.jackson.core:jackson-databind")
}


  • Controllerクラス
    • パターン1:Json形式の文字列で受け取り
FrontController.java
@Controller
public class FrontController {

    @Autowired
    private FrontService frontService;

    @RequestMapping({ "/", "/index" })
    public String index() {
        return "index";
    }
    @ResponseBody
    @RequestMapping(value = "/getAddress" ,method = RequestMethod.POST, produces="application/json;charset=UTF-8")
    public String getAddress(@RequestBody(required = false) AddressForm addressForm) {
        return frontService.getAddress(addressForm.getZipcode());
    }
}
  • Serviceクラス
FrontService.java
public interface FrontService {
    public String getAddress(String zipCode);
}
FrontServiceImpl.java
@Service
public class FrontServiceImpl implements FrontService {

    /** 郵便番号検索API リクエストURL */
    private static final String URL = "https://zip-cloud.appspot.com/api/search?zipcode={zipcode}";

    @Override
    public String getAddress(String zipCode) {
        String zipCodeJson = restTemplate.getForObject(URL, String.class, zipCode);
        return zipCodeJson;
    }
}
  • formクラス
AddressForm.java
@Data
public class AddressForm {

    /** 郵便番号 */
    String zipcode;
}

4.フロントエンドの実装

  • html
index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>address</title>
        <script type="text/javascript" th:src="@{/jquery/jquery-3.3.1.js}"></script>
        <script th:src="@{/js/index.js}"></script>
    </head>
    <body>
        <form name="getAddress">
            <input id="zipcode" type="text">
            <button type="button" id="getAddressBtn">住所取得</button>
            <div id="dispAddress"></div>
        </form>
    </body>
</html>
  • JavaScript
index.js
$(function() {
    $('#getAddressBtn').on('click', function() {
        var params = {
                "zipcode" : $('#zipcode').val()
        };
        $.ajax({
            url : 'getAddress',
            type: 'POST',
            contentType: "application/json",
            data: JSON.stringify(params),
            dataType : 'json',
            async: false,
            success: function (data) {
                $("#dispAddress").empty();
                var dispAddress = document.getElementById("dispAddress");
                var table = document.createElement("table");
                table.setAttribute("border","2");
                table.setAttribute("cellpadding","15");
                table.setAttribute("style","margin :15px");

                $(data.results).each(function(index, result){
                    table.appendChild(createRow("郵便番号",result.zipcode));
                    table.appendChild(createRow("都道府県コード",result.prefcode));
                    table.appendChild(createRow("都道府県名",result.address1));
                    table.appendChild(createRow("市区町村名",result.address2));
                    table.appendChild(createRow("町域名",result.address3));
                    table.appendChild(createRow("都道府県名カナ",result.kana1));
                    table.appendChild(createRow("市区町村名カナ",result.kana2));
                    table.appendChild(createRow("町域名カナ",result.kana3));
                });
                dispAddress.appendChild(table);
            }
        });
    });
});

function createRow(header , value){
    var tr = document.createElement("tr");
    var th = document.createElement("th");
    th.append(header);
    var td = document.createElement("td");
    td.append(value);
    tr.appendChild(th);
    tr.appendChild(td);
    return tr;
}

5.動作確認

  • ブラウザで「localhost:8080」にアクセス
    ブラウザ起動.png

  • 「100-0001」(皇居の郵便番号)を入力して住所取得ボタン押下
    ブラウザ起動2.png

  • 住所が表示された。

6.おまけ

Json形式をDTOクラスに変換して受け取る方法
- Controllerクラス

FrontController.java
@Controller
public class FrontController {

    @Autowired
    private FrontService frontService;

    @RequestMapping({ "/", "/index" })
    public String index() {
        return "index";
    }
    @ResponseBody
    @RequestMapping(value = "/getAddress" ,method = RequestMethod.POST, produces="application/json;charset=UTF-8")
    // 戻り値をString → ZipcodeDto に変更
    public ZipcodeDto getAddress(@RequestBody(required = false) AddressForm addressForm) {
        return frontService.getAddress(addressForm.getZipcode());
    }
}
  • Serviceクラス(修正)
FrontService.java
public interface FrontService {
    // 戻り値をString → ZipcodeDto に変更
    public ZipcodeDto getAddress(String zipCode); 
}
  • DTOクラス(追加)
ZipcodeDto.java
@Data
public class ZipcodeDto {
    /** ステータス */
    int status;

    /** メッセージ */
    String message;

    /** 郵便番号情報リスト */
    List<ZipcodeResultDto> results = new ArrayList<>();
}
  • DTOクラス(追加)
ZipcodeResultDto.java
@Data
public class ZipcodeResultDto {

    /** 郵便番号 */
    String zipcode;

    /** 都道府県コード */
    String prefcode;

    /** 都道府県名 */
    String address1;

    /** 市区町村名 */
    String address2;

    /** 町域名 */
    String address3;

    /** 都道府県名カナ */
    String kana1;

    /** 市区町村名カナ */
    String kana2;

    /** 町域名カナ */
    String kana3;
}

  • Service実装クラス
    • ObjectMapperにURLを渡してDTOクラスに変換するパターン
FrontServiceImpl.java
@Service
public class FrontServiceImpl implements FrontService {
     // ObjectMapperを追加
    @Autowired
    ObjectMapper objectMapper;

     // URLのパラメータを正規表現に変更
    private static final String URL = "https://zip-cloud.appspot.com/api/search?zipcode=%s";

    @Override
    public ZipcodeDto getAddress(String zipCode) {
        ZipcodeDto zipcodeDto = null;;
        try {
            // ObjectMapperでURLと受け取りクラスを指定
            java.net.URL url = new java.net.URL(String.format(URL,zipCode));
            zipcodeDto = objectMapper.readValue(url, ZipcodeDto.class);
        } catch (Exception e) {
            e.getStackTrace();
        }
        return zipcodeDto;
    }
}
  • Service実装クラス
    • restTemplateにMappingJackson2HttpMessageConverterを設定して変換するパターン
FrontServiceImpl.java
@Service
public class FrontServiceImpl implements FrontService {

     // restTemplateを追加
    RestTemplate restTemplate = new RestTemplate();

    private static final String URL = "https://zip-cloud.appspot.com/api/search?zipcode={zipCode}";

    @Override
    public ZipcodeDto getAddress(String zipCode) {
        ZipcodeDto zipcodeDto = null;;
        try {

           // reatTemplateのmessageConverterにMappingJackson2HttpMessageConverter を追加
            MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
            List<MediaType> supportedMediaTypes = new ArrayList<>(messageConverter.getSupportedMediaTypes());
            supportedMediaTypes.add(MediaType.TEXT_PLAIN);
            messageConverter.setSupportedMediaTypes(supportedMediaTypes);
            restTemplate.setMessageConverters(Collections.singletonList(messageConverter));
            zipcodeDto = restTemplate.getForObject(URL, ZipcodeDto.class, zipCode);
        } catch (Exception e) {
            e.getStackTrace();
        }
        return zipcodeDto;
    }
}

7.まとめ

  • APIを使用するのは簡単(認証機能付きはもう少し難しい)
  • 他APIからデータ活用できる
  • いろんなAPIを組み合わせて新しいサービスを作れそう。
15
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13