17
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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の確認

|  パラメータ名  |  項目名  |  必須  |  備考  |
| ---- | ---- | ---- | ---- |
|  zipcode  |  郵便番号  |  ○  |  7桁の数字。ハイフン付きでも可。完全一致検索。  |
|  callback  |  コールバック関数名  |  -  |  JSONPとして出力する際のコールバック関数名。UTF-8でURLエンコードした文字列。  |
|  limit  |  最大件数  |  - |  同一の郵便番号で複数件のデータが存在する場合に返される件数の上限値(数字) ※デフォルト:20  |
  • レスポンスパラメータ
|  フィールド名	 |  項目名  |  備考  |
| ---- | ---- | ---- |
|  status  |  ステータス  |  正常時は 200、エラー発生時にはエラーコードが返される  |
|  message  | メッセージ  |  エラー発生時に、エラーの内容が返される。  |
|  results  | zipcode(郵便番号) <br> prefcode(都道府県コード)<br> address1(都道府県名) <br> address2(市区町村名)<br>address3(町域名) <br>kana1(都道府県名カナ)<br>kana2	(市区町村名カナ) <br>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を組み合わせて新しいサービスを作れそう。
17
14
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
17
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?