patternMinor
API for looking up Japanese postal code
Viewed 0 times
japaneselookingforcodeapipostal
Problem
Most of my experience is in Python, Java and embedded C, and I need to learn Scala and Play for a new job. As an exercise, I decided to create a very simple API for looking up area by postal code, backed by Redis. It's just a single controller with a couple of routes.
I'm hoping for feedback from experienced Scala or Play users. Please suggest any improvements to make the code more readable, maintainable, idiomatic, performant, secure etc. As a starting point, I enabled several static analysis tools in my build and fixed the issues reported.
controllers/JPI.scala
```
package controllers
// Scala imports
import util.control.Breaks._
// Play imports
import play.api.mvc._
import play.api.Play.current
import play.api.cache.Cache
import play.api.libs.json._
import com.typesafe.plugin.RedisPlugin
// Java imports
import java.io.{BufferedReader, InputStreamReader}
import java.net.URL
import java.util.zip.ZipInputStream
object JPI extends Controller {
final val JapaneseURI = "http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip"
final val TestURI = "http://localhost:9000/assets/ken_all.zip"
final val CSVEncoding = "SJIS"
final val PostalCodeMin = 0
final val PostalCodeMax = 9999999
final val PostalCodeFmt = "%07d"
final val CSVFields = List(
("prefecture_kana", 3),
("municipality_kana", 4),
("neighbourhood_kana", 5),
("prefecture_kanji", 6),
("municipality_kanji", 7),
("neighbourhood_kanji", 8)
)
/**
Lookup a numeric postal code in the Redis cache
*/
def lookup(postalCode: Integer) = Action {
if (postalCode PostalCodeMax) {
NotFound(
"Postal code outside valid range (%s to %s)".format(
fmt(PostalCodeMin), fmt(PostalCodeMax)
)
)
} else {
val json: Option[String] = Cache.getAsString
json match {
case None => NotFound("Postal code not found")
case Some(j) => Ok(j).as("application/json; charset=utf-8")
}
I'm hoping for feedback from experienced Scala or Play users. Please suggest any improvements to make the code more readable, maintainable, idiomatic, performant, secure etc. As a starting point, I enabled several static analysis tools in my build and fixed the issues reported.
controllers/JPI.scala
```
package controllers
// Scala imports
import util.control.Breaks._
// Play imports
import play.api.mvc._
import play.api.Play.current
import play.api.cache.Cache
import play.api.libs.json._
import com.typesafe.plugin.RedisPlugin
// Java imports
import java.io.{BufferedReader, InputStreamReader}
import java.net.URL
import java.util.zip.ZipInputStream
object JPI extends Controller {
final val JapaneseURI = "http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip"
final val TestURI = "http://localhost:9000/assets/ken_all.zip"
final val CSVEncoding = "SJIS"
final val PostalCodeMin = 0
final val PostalCodeMax = 9999999
final val PostalCodeFmt = "%07d"
final val CSVFields = List(
("prefecture_kana", 3),
("municipality_kana", 4),
("neighbourhood_kana", 5),
("prefecture_kanji", 6),
("municipality_kanji", 7),
("neighbourhood_kanji", 8)
)
/**
Lookup a numeric postal code in the Redis cache
*/
def lookup(postalCode: Integer) = Action {
if (postalCode PostalCodeMax) {
NotFound(
"Postal code outside valid range (%s to %s)".format(
fmt(PostalCodeMin), fmt(PostalCodeMax)
)
)
} else {
val json: Option[String] = Cache.getAsString
json match {
case None => NotFound("Postal code not found")
case Some(j) => Ok(j).as("application/json; charset=utf-8")
}
Solution
I'm skeptical of accepting postal codes as
Furthermore, an API that is designed to take an integer could never be extended to countries like the UK and Canada, where postal codes are alphanumeric. It would also be problematic for US ZIP+4 codes, which, despite being mostly numeric like Japanese codes, may overflow an
Integers. Japanese postal codes are of the format NNN-NNNN. Accepting a String, which may contain an optional hyphen and leading zeros, would be more appropriate.Furthermore, an API that is designed to take an integer could never be extended to countries like the UK and Canada, where postal codes are alphanumeric. It would also be problematic for US ZIP+4 codes, which, despite being mostly numeric like Japanese codes, may overflow an
Integer. (It's odd that you take an Integer instead of an Int, but that's a moot point.)Context
StackExchange Code Review Q#78378, answer score: 4
Revisions (0)
No revisions yet.