日本郵便での日本からのEMS配送料を算出するAPIを公開してみた。

前回の記事に引き続き、 過去の作ったものでブログを書いてみるシリーズの第2弾です。

前回はこっち。 webuilder240.hatenablog.com

前にこの記事を書きましたが、 webuilder240.hatenablog.com

これをAPIで公開しました。 Productionで使われることはそこまで気にしていないんで、HerokuのHobbyインスタンスで適当にやっています。 自前で欲しい場合はHerokuButtonもないので、公開しているリポジトリから適当にやってください。 他の404も手抜きです。今後使う人が増えてくればやろうかなぁと言う感じ。

API: https://from-jp-ems.herokuapp.com

Repo: github.com

使い方

curl -X GET https://from-jp-ems.herokuapp.com?area=asia&weight=100 | jq

Response

{
  "result": 200,
  "area": "asia",
  "weight": 100,
  "amount": 1400
}

ざっくり仕様

  • weightは数値型で1〜30000のグラム単位の値。
  • area は “asia”, “oceania”, “north_america”, “middle_east”, “central_america”, “europa”, “africa”, “south_america"のいずれか。

料金表についてはをここを参照してください。(エンドポイントを追加しようかな。) www.post.japanpost.jp

ちょっと工夫した点

ほとんど算出するロジックはGemで実装しているし、ほとんどやることは無かったと言っても過言ではない。 まぁでも若干苦労したところがあったので、簡単に書いておく。

weightが文字列だったときの対応

このAPIの場合、weightに渡すパラメータは数値型、Integerである必要がある。 なのでざっくりIntegerに変換する方法をとった。 ちなみにto_iだったら、"100kg"がパラメータとして渡ったときに100と返してしまうので使えなかった。 Integerで変換して文字列だったときはrescueでキャッチして、数値を0にするようにした。(もっと他にありそう。)

  def weight=(value)
    begin
      value = Integer(value)
    rescue TypeError, ArgumentError
      value = 0
    end
    @weight = value
  end

そのうち何らかの形でkg単位のAPIなんかもサポートしたいと思っている。

実行できるメソッド

areaで渡ってきたパラメータをそのままバリデーションして実行したかったので、 ライブラリで定義されているクラスメソッドの一覧を取得して、そのリストでValidateするようにした。 特異メソッドなので、singleton_methodsで取得。 ソースコードで言うとこんなところ。

  ALLOW_AREAS = JpEmsFee.singleton_methods.map(&:to_s)
  validates :area, inclusion: { in: ALLOW_AREAS }

あとはなるべくControllerに処理を書かないようにしたくらい。 本当はDecorator層とかに書けよってものもModelに書いてるけど、 本当に小さなAPIなので気にしない。

反省点・今後のTODO

Docker

今回は面倒だったのでやらなかった。 これは今後Herokuで動かせるようにしつつやっつける。

Rails API

API用途だけなので、Rails API使ってみればよかった。 他の不要なGemを掃除できたのでそのうち対応してみる。

Request Rspec

まだ書いてない。正直書くボリュームでもないかな。とも。

Swagger

使ってみればよかった…

最後に

僕の働いているオシロ株式会社ではエンジニアを募集しています。

手前味噌ですが、面白い福利厚生や会社制度もありますし、 普通のWebサービスではあまりないような課題があるので、Railsをバリバリ書ける環境で、やりがいがあるんじゃないかなと思っています。 Railsを覚えたい他の言語でのご経験のあるエンジニアさんも大歓迎です!!

まずは話を聞いていただけるだけでもとても嬉しいので、まずはWantedlyの募集ページを見てみてください! 何卒よろしくお願いいたします。

www.wantedly.com

PHPのシンプルなファイルキャッシュの仕組みを作ってみた。

大げさな事を言っているけど、単にAPI何かのレスポンスをキャッシュしたいときに雑に扱えるものを作った。という感じ。 類似ライブラリはあるっちゃあるけど、このくらいの実装だったら自分でメンテしたほうが良いと思ってる。 公開も面倒なので雑にGistにした。使い方もGistを参照して欲しい。

simple file base cache for php

Expireは?

expireは用途によってExpireするタイミングとかって違うだろうし、メンテも面倒なので気が向いたら書くか〜という感じ。

Packgistに公開は?

現状していない。ぶっちゃけ自分でPHP書く案件はとても小さな案件が多いだろうし、Composerすらいれるのが面倒なのである。(主にWordPressだったり素のPHP案件) とはいえ、このライブラリで市民権を得たいという気持ちもあるので、テストが書けたら1.0.0としてリリースを検討している。

まとめ

  • こういったとってもシンプルなライブラリを作っておく or 類似ライブラリを見つけることで自分の小さいサービスを作るときに多いに役立つ。
  • FBやインスタなんかのAPIを叩いて作るライブラリなんかはこういうのを雑に導入しておくととても効率が良い。
  • そのうちRuby版作ってみる。

最後に

僕の働いているオシロ株式会社ではエンジニアを募集しています。

メインで触っているのはRubyだったりするのですが、少しPHPの業務もあったりするし、 Rubyをやってみたくて悶々としているPHPエンジニアさんも大歓迎です!

まずは話を聞いていただけるだけでもとても嬉しいので、まずはWantedlyの募集ページを見ていただけると幸いです。 何卒よろしくお願いいたします。

www.wantedly.com

決済サービスが用意している定期課金機能でWebサービスの定期課金の仕組みを作るべきでない事例をまとめた

ということなんで、書いてみました。

決済サービスが用意してくれている定期課金の仕組みは利用しないほうがいいと個人的には思っている。 1年以上この仕組みでやってきたが、なかなか弊社案件ではちょっとつらいものがあって、今後のために色々書いておこうと思ったので書いた。

先に書いておきますが、利用している決済サービスに対しては概ね満足しており、 特定の決済サービスへの批判ということではないということをご了承いただきたいです。

いきなりまとめ

  • サービスロックインが心配
  • イレギュラーな事例への対応ができない(しにくい)から。
  • 複数決済サービスの利用時に期間や挙動に細かい差異の吸収ができない。
  • 要件がかっちり決まっており、仕様変更が未来永劫ないか、今後実装変更のために時間を利用できる場合は自前実装はしなくてもいい。

ということで、理由をざっくり説明したいと思う。

1. サービスロックイン

これは最近あった事例だけど、決済サービスが大手企業がバックに付いていても某社の様にサービスがなくなるかわからない。 スタートアップ企業とはそういうものだし、そんなときに定額課金を各サービスに依存している場合、相当苦労することだろう。 移行先の決済サービスに定額課金の機能が存在していても、(殆どのサービスのところは存在しているはず)

細かい挙動(次の決済日時算出ロジック)が違ったりして、意図しない課金日に設定されたりということがあるいうことを考えるとそのまま全く同じに移行して動くという保証はない。

こういったリスクを最小限に抑える場合は、自前で定期課金の仕組みを実装するべきである。 当然再実装は必要になる部分はどっちにしろあるけど、殆どの場合で同じように動かすのは容易だと思う。

大きく決済周りの実装を要件の変更に対応することもあるだろうから、 その際に、「特定のサービスに依存していない」というのは強みになると思う。

特に弊社では決済周りの実装がカスタマーによって細かく異なるケースも存在する可能性もあることから、 サービスロックインは無い方が良いのでは?と思い始めているというのも理由の一つだと思う。 

2. イレギュラーに対応できない。

イレギュラーといっても色々あるが、簡単にいえば決済サービスが定期課金のAPIで実装されていないけどやりたいことの全部である。 日割り計算が決済サービスの定額課金APIでなければそれだし、 他にも複数のプランがあって、途中のプランのアップグレードやダウングレードを考慮するときに、 「差分だけ支払ってアップグレードする」ということが難しいというか、定期課金のAPIで実装されてない場合。仕組み上不可能に近い。

他にも「XXXXできますか?」「XXXに対応しないといけない」という特殊な要望もあるだろう。 それを今後対応する場合でも最初から見据えて実装するべきである。 これらに対して柔軟に対応したい、ということを考えると自前定期課金の仕組みを実装するべきだと思う。

3. 複数決済サービスの利用時の期間や挙動に細かい差異が生じる

課金を取り扱うサービスの場合、複数の決済サービスを利用することが可能性としてあがってくる事がある。 クレジットカード決済でも審査の都合からJCBが使えないというトラブルもあり、Paypalをイレギュラーに利用する場合もあるだろう。

他にも銀行振込の決済サービス・携帯のキャリア決済・コンビニ払い、さらには外貨サービスは別かも…と、 多種多様の支払い方法があり、それらに対してすべての支払い方法を対応するようなケースも想定される。

当然すべての支払い方法がカバーされている決済サービスを利用すれば良いのだが、 手数料やビジネス上の問題から、それぞれの支払い方法で最適な決済サービスを選ぶこともあるだろう。

会社・サービスが異なると、基準となるタイムゾーンなどが異なる場合もあり、決済サービスと自分たちの意図している課金日がずれてしまったりすることも存在し、 課金日を厳格にアプリケーション側で管理したいような性質のサービスの場合は、決済サービスで自前で定期課金の仕組みを作った方が圧倒的に気楽である。

まとめ

簡単ではあるが、定期課金処理について少し困ったことを吐き出してみた。

決済サービスに依存した定期課金処理は実装もラクで便利ではあるが、 使いどころを間違えると後で痛い目に遭うので、導入には大いに時間をかけて検討するべきである。 この記事を決済処理を実装する前の自分におくりたかった…

やっぱり弊社案件では定期課金に対しても柔軟性が必要になるケースがあるかもなので、 これから時間を作って、定期課金の実装を自前のものに載せ替えることを検討している。

参考記事とか

www.bokukoko.info www.bokukoko.info

最後に

僕の働いているオシロ株式会社ではエンジニアを募集しています。

手前味噌ですが、面白い福利厚生や会社制度もありますし、 普通のWebサービスではあまりないような課題があるので、やりがいがあるんじゃないかな。と思っています。 まずは話を聞いていただけるだけでもとても嬉しいので、まずはWantedlyの採用ページを見てみてください。 何卒よろしくお願いいたします。

www.wantedly.com

RubyでJSONをオブジェクトっぽくアクセスできるようにしたい。

1年以上Ruby触ってきたけど知らなかった。のでメモ代わりに書いておく。

# APIリクエストした内容
post = JSON.parse(response.body, class_object: OpenStruct)

# <OpenStruct id=1, title="test", body="test", publish_date="2017-07-26T13:31:00.000Z", created_at="2017-07-26T13:31:26.340Z", updated_at="2017-07-26T13:31:26.340Z">
# post.title, post.bodyでアクセスが可能。

使いみち

  • APISDKをシュッと作りたいとき。
  • 普通のサーバーサイドアプリケーションのModel取得部分をAPIで実装したいとき。
  • 別に無理やりアプリでAPI使いたいから無理してSPAにする必要はなくて、非SPAのままRailsのView使いたいときなんかはコレ使えばある程度は大丈夫そう。 (そもそもRailsの場合はActiveResource使っても良い感じもするが。)

参考URL

stackoverflow.com

最後に

僕の働いているオシロ株式会社ではエンジニアを募集しています。

手前味噌ですが、面白い福利厚生や会社制度もありますし、 普通のWebサービス・スタートアップではあまりないような技術的課題もあって、 やりがいがあるんじゃないかなと思っています。

まずは話を聞いていただけるだけでもとても嬉しいので、ここからご連絡していただけると嬉しいです。 よろしくお願いいたします。

osiro.it

2017/05/12の日記

VisualStudio for Macを使ってみた。

と言ってもプレビュー版からの1年近い長い付き合いではある。 最近起動していなかったので、久しぶりに使ったのだけど楽しかった。

型でこの変数はどういうものなのか、というのがひと目で分かるのでそれはそれでよかった。 色々実装がRubyに比べるとそりゃ冗長な感じは否めないけど、全然許容範囲内。 次の趣味プロダクトではC#での実装を検討している。(C#OSSなECプラットフォームを作ってみたい。)

C# ≒ TypeScript

最近プロダクトでTypeScriptの導入を検討している。 やむにやまれぬ事情で、VueをつかったSPAチックな実装から、サーバーサイドレンダリングしたDOMに対して、 jQueryないし、PureJSで操作するような実装に舵を切ったからで、 まともなフレームワークを使わないような方針で戦っていく場合、型が有効なのでは? とふと思いついたからである。

あとTypeScriptだったら、現行で使用しているコードの流用も容易で、 あとからガシガシ型を付けていけるという選択肢も取れそうかな。というのも思案の一つ。

そういったTypeScriptの敷居の低さと型推論のあるC#には似たようなものを感じた。 やっぱり作った人が同じなのでそうなるのは当然なのかな。