ブラウザおよびnode.js用のAxiosベースの宣言型HTTPクライアント。
宣言型 HTTP クライアントに慣れた Java プログラマーによって作成されました。
目標は、すべての JavaScript/typescript 環境 (実際には es6 環境) でシンプルで簡潔な http クライアントを提供することです。 ( まだ! )
babel-plugin-transform-decorators-legacy
まだパラメータ デコレータをサポートしていないため、現時点では RetrofitJ は TypeScript 環境でのみ動作します。
ここで提案を引用します。
フィールド、ゲッター、セッター、メソッドの宣言だけでなく、クラス全体を修飾することもできます。引数と関数宣言は装飾できません。 -- プロポーザルデコレーターより
また、誰かがこのリクエストを提出しました --> パラメータ デコレータ?
ここで、Retrofit と同じように、http の詳細ではなく、独自の http インターフェイスを宣言することに焦点を当てて、記述を減らし、より多くのことを実行しましょう。
最後に、Axios ( javascript http client ) と Retrofit (java http client ) を書いたり更新したりしてくれたすべての人々に深く感謝します。これらは素晴らしいプロジェクトであり、私に多くのことを教えてくれました。
このプログラムは、 Proxy
オブジェクト ( es6 ) とDecorator
機能 (ステージ 2 ) に依存しているため、IE8/9/10/11 および es6 をネイティブでサポートしていないその他の環境 (通常はブラウザ) では動作しません。
言い換えれば、RetrofitJ は es6 をネイティブでサポートするあらゆる環境で動作することができます。
Proxy
オブジェクトについて、サポートされているポリフィルが見つかりません。ただし、 Decorator
の場合は、 babel-plugin-transform-decorators-legacy
などの babel サポートによって使用できます。
npm の使用:
npm install retrofitjs
// This is typescript demo, also javascript demo( it is if you remove all type define )
// In the first step, you must create your retrofit object.
let client = Retrofit . getBuilder ( )
. setConfig < RetrofitConfig > ( { /** config, you can use retrofit config or axios config */ } )
. addInterceptor ( /** your interceptor */ )
. setErrorHandler ( /** define your error handler */ )
. build ( ) ;
// This is the part of define any interface what you need.
@ HTTP ( "/testing" )
@ Headers ( [ "Cache-Control: no-store" ] )
class TestingClient {
@ GET ( "/demo1/:callByWho/:when" )
public demo1 ( @ Path ( "callByWho" ) name : string , @ Path ( "when" ) time : number ) : RetrofitPromise < string > & void {
}
@ POST ( "/demo2/:file" )
public demo2 ( @ Path ( "file" ) file : string , @ Header ( "cookie" ) val : string , @ Config localConfig : AxiosConfig ) : RetrofitPromise < string > & void {
}
}
// The final step, create your client.
export let testingClient = client . create ( TestingClient ) ;
// When you are calling this method, it is a http call actually.
testingClient . demo1 ( "itfinally" , Date . now ( ) ) . then ( response => {
// any code
} ) . catch ( reason => {
// any code
} ) ;
// And you can also get axios instance.
let axios : AxiosInstance = client . getEngine ( ) ;
Retrofit と同様に、RetrofitJ もインターセプター チェーンによって実装されます。すべてのインターセプタはorder
フィールドによって並べ替えられ、最大から最小の順に並べ替えられます。
// This is a interceptor interface
export interface Interceptor {
order : number ;
init ( config : RetrofitConfig ) : void ;
intercept ( chain : Chain ) : Promise < ResponseInterface < any > >
}
RealCall
インターセプターは最後のインターセプターであり、そうである必要があることに注意してください。
これはデフォルトのインターセプタであり、 order
フィールドの値はゼロです。 RetrofitJs は、Axios オブジェクトによるすべての http リクエストを送信するためにこれを使用しました。
競合を避けるため、順序フィールドの数は 256 未満 ( 256 は含まれません) 予約されています。
このように、独自のインターセプターを簡単に実装できます。
class MyInterceptor implement Interceptor {
public order : number = 256 ;
public init ( config : RetrofitConfig ) : void {
// Initializing your interceptor
}
public intercept ( chain : Chain ) : Promise < ResponseInterface < any > > {
// Your code
return chain . proceed ( chain . request ( ) ) ;
}
}
chain.proceed( chain.request() )
、このコードはリクエストが続行されるかどうかを決定することに注意してください。
chain.proceed
で呼び出すと、現在のリクエストは次のインターセプタに転送されます。そうしないと、残りのインターセプターがアクティブになりません。また、インターセプター チェーンからエラーがスローされた場合、プロセス全体が終了し、エラー ハンドラーがアクティブになります。
実際、プラグインはインターセプタです。RetrofitJ 用に独自のプラグインを作成できます。
Retrofit.use( new MyInterceptor implements Interceptor {
public order: number = 20;
public init( config: RetrofitConfig ): void {
}
public intercept( chain: Chain ): Promise<ResponseInterface<any>> {
}
} );
インスタンスの作成時に、すべてのインターセプターがRetrofit
に追加されます。
プラグインの順序フィールドに制限はありません。実際、プラグインとデフォルトのインターセプタ用に予約されている番号があります。
そして、これはすべてデフォルトのインターセプターです。
インターセプター | 注文 |
---|---|
リアルコール | 0 |
RetryRequestInterceptor | 1 |
ロガーインターセプター | 5 |
このインターセプタはデフォルトでは無効になっており、冪等リクエストにネットワーク異常がある場合、ランダムな時間で再試行します。 「GET」リクエストを送信したときの接続タイムアウトなど。
これを使用したい場合は、 RetrofitConfig
でmaxTry
とtimeout
設定する必要があります。
RetrofitConfig
で設定できます。
{
"maxTry": "number",
"retryCondition": "RetryCondition"
}
RetryCondition
はインターフェースであり、 RetryCondition.handler
true を返した場合、インターセプターはリクエストの再送信を試みます。
このインターセプターはデフォルトで無効になっており、すべてのリクエスト/レスポンス (またはエラー) を記録し、コンソールに出力します。
RetrofitConfig
で設定できます。
{
"debug": "boolean"
}
リクエストを簡単にキャンセルできます。
let tick = testingClient . demo1 ( ... args ) ;
// Careful the different between micro task and macro task
setTimeout ( ( ) => tick . cancel ( "your message" ) , 3000 ) ;
注意: cancel
API はRetrofitPromise
オブジェクトのメソッドであり、他の Promise オブジェクトで呼び出すことはできません。これは例です。
// It is wrong.
tick . then ( ( ) => { ... you code } ) . cancel ( "message" ) ;
リクエストをキャンセルするとRequestCancelException
がスローされますが、エラー ハンドラで処理するか無視することができます。
すべての例外を統一的に処理したい場合は、 ErrorHandler
実装するだけです。
class MyErrorHandler implement ErrorHandler {
public handler ( realReason : any , exception : Exception ) : void {
// your code
}
}
realReason
は axios によって与えられるパラメータであり、 exception
Exception
のインスタンスであり、すべての例外を簡単に均一に処理できます。
これはすべて例外です。
例外 | 説明 |
---|---|
リクエストキャンセル例外 | ユーザーのキャンセル |
接続例外 | ECONNREFUSED 信号がアクティブ化されました |
ソケット例外 | ECONNRESET信号活性化 |
リクエストタイムアウト例外 | ECONNABORTED または ETIMEDOUT 信号がアクティブ化される |
IO例外 | 残りの未知の状況 |
エラー ハンドラーはすべての例外をキャッチできますが、 Promise.catch
アクティブでなくなるわけではありません。実際には、例外がスローされたときに通常のプロセスを終了するための理由で必要です。
class MyErrorHandler implement ErrorHandler {
public handler ( realReason : any , exception : Exception ) : void {
// Your code
}
}
testingClient . demo1 ( ... args ) . then ( response => {
// Normal business process
} ) . catch ( reason => {
// Active after error handler call
} ) ;
単一のメソッド記号では、単一のパラメータをマルチデコレータで装飾することはできません。
// It is wrong!
public demo1 < T > ( @ Field ( "key1" ) @ Header ( "header1" ) val1 : any ) : RetrofitPromise < T > & void {
}
https://127.0.0.1/demo?key1=val1&key2=val2
のような URL クエリを作成したい場合は、次のように実行します。
public demo1 < T > ( @ Query ( "key1" ) val1 : any , @ QueryMap map1 : object ) : RetrofitPromise < T > & void {
}
@Query
クエリのキーと値のエントリを宣言します。@QueryMap
クエリの複数のキーと値のエントリを宣言します。簡単にフォームを送信できます。
@ FormUrlEncoded
public demo1 < T > ( @ Field ( "key1" ) val1 : any , @ FieldMap map1 : object ) : RetrofitPromise < T > & void {
}
@Field
および@FieldMap
メソッドが@FormUrlEncoded
によって宣言されている場合にのみ有効です。
@FormUrlEncoded
これがフォームであることを宣言します。@Field
フォームのキーと値のエントリを宣言します。@FieldMap
複数のキーと値のエントリの形式を宣言します。jsonボディでリクエストしたい場合は、 @Body
を使ってパラメータを装飾します。
public demo1 < T > ( @ Body myBody : object ) : RetrofitPromise < T > & void {
}
@Body
1 つのリクエストに 1 つの本文があるため、 @FormUrlEncoded
または@MultiPart
と一緒に使用することはできません。また、 @Body
同じメソッド記号内で複数使用することはできません。
// It is wrong!
public demo1 < T > ( @ Body myBody : object , @ Body otherBody : object ) : RetrofitPromise < T > & void {
}
上記の場合と同様に、パラメータmyBody
無視されます。
設定をオーバーライドしたい場合は、 @Config
を使用してパラメータを装飾します。
public demo1 < T > ( @ Config config : RetrofitRequest ) : RetrofitPromise < T > & void {
}
パラメータ設定に含まれるフィールドによってデコレータ設定(ただしグローバル設定は含まれません)をオーバーライドします。
動的構成はリクエストでのみ有効ですが、インターセプター構成には有効ではありません。これは、インターセプターの初期化はRetrofit.getBuilder().build()
の呼び出し時に行われ、初期化は 1 回だけであるためです。
次のように、RetrofitJs を使用してファイルを簡単にアップロードできます。
@ MultiPart
@ PUT ( "/upload" )
public upload ( @ Part ( "file" ) file : any , @ PartMap anything : any ) : RetrofitPromise < void > & void {
}
これはブラウザの方法です:
// document.getElementById( "file" ) is a input tag
client . upload ( document . getElementById ( "file" ) . files [ 0 ] ) ;
そしてこれがノードウェイです:
// create a file read stream as parameter, done.
client . upload ( fs . createReadStream ( "your file path" ) ) ;
フォーム送信と同様に、 @Part
および@PartMap
もメソッドが@MultiPart
によって宣言されている場合にのみ有効です。
@MultiPart
これがフォームであると宣言します。@Part
フォームのキーと値のエントリを宣言します。@PartMap
複数のキーと値のエントリの形式を宣言します。また、サーバーの最大ファイル サイズの設定にも注意する必要があります。ファイルサイズがサーバーの制限を超えると、アップロードは常に失敗します。
最後に、 Buffer
オブジェクトをパラメータとして使用しない」で、アップロードにバッファ オブジェクトを使用しようとしましたが、バッファ オブジェクトにはデータのみが含まれ、ファイル名、ファイルタイプなどの説明が含まれていないため、すべて失敗しました。
ブラウザでは、Ajax は常に文字列データで応答するため、Ajax でファイルをダウンロードする方法はありませんが、タグ iframe を使用してブラウザのダウンロードをアクティブにすることができます。
次のように、ノードにファイルをダウンロードできます。
@ ResponseBody ( ResponseType . STREAM )
public demo1 ( ) : RetrofitPromise < Stream > & void {
}
@ResponseBody
どの型を返す必要があるかを RetrofitJ に伝えます。
これはすべてサポートされている応答タイプです。
タイプ | 価値 |
---|---|
物体 | ResponseType.JSON (デフォルト) |
弦 | ResponseType.DOCUMENT、ResponseType.TEXT |
ストリーム | 応答タイプ.STREAM |
バッファ | 応答タイプ.ARRAY_BUFFER |
これが最後の章です。ご覧のとおり、RetrofitJ はプラットフォームのみを提供し、すべての http インターフェイスは自分で作成する必要があります。
また、共通のインターフェイスを作成して拡張することもでき、情報コレクターは次のように動作します。
つまり、情報の優先順位チェーンは次のようになります: @Config > メソッド > このクラス > スーパー クラス
マサチューセッツ工科大学