183 lines
5.1 KiB
Markdown
183 lines
5.1 KiB
Markdown
<!--
|
|
* Copyright (C) 2022 WYATT GROUP
|
|
* Please see the AUTHORS file for details.
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
-->
|
|
|
|
# Dart - HTTP Client
|
|
|
|
<p align="left">
|
|
<a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis">
|
|
<img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" />
|
|
</a>
|
|
<img src="https://img.shields.io/badge/SDK-Dart%20%7C%20Flutter-blue?style=flat-square" alt="SDK: Dart & Flutter" />
|
|
</p>
|
|
|
|
HTTP Client for Dart with Middlewares !
|
|
|
|
## Getting started
|
|
|
|
Simply add wyatt_http_client in pubspec.yaml, then
|
|
|
|
```dart
|
|
import 'package:wyatt_http_client/wyatt_http_client.dart';
|
|
```
|
|
|
|
## Usage
|
|
|
|
Firstly you have to understand **Middleware** and **Pipeline** concepts.
|
|
|
|
In `wyatt_http_client` a middleware is an object where requests and responses
|
|
pass through. And a pipeline is basicaly a list of middlewares.
|
|
|
|
In a pipeline with middlewares A and B, if request pass through A, then B,
|
|
the response will pass through B then A.
|
|
|
|
> You can `print(pipeline)` to get full process order of a pipeline.
|
|
|
|
For example, if you want to log every request, and simplify an url you can use provided `SimpleLogger` and `UriPrefix` .
|
|
|
|
```dart
|
|
// Create the Pipeline
|
|
final Pipeline pipeline = Pipeline()
|
|
.addMiddleware(
|
|
UriPrefixMiddleware(
|
|
protocol: Protocols.http,
|
|
authority: 'localhost:80',
|
|
),
|
|
)
|
|
.addMiddleware(SimpleLoggerMiddleware());
|
|
```
|
|
|
|
Then if you print the pipeline,
|
|
|
|
```
|
|
[Req] -> UriPrefix -> SimpleLogger
|
|
[Res] -> SimpleLogger
|
|
```
|
|
|
|
> The `response` doesn't pass through `UriPrefix` because it's an `OnRequestMiddleware` only.
|
|
|
|
And you can create a client.
|
|
|
|
```dart
|
|
final client = MiddlewareClient(pipeline: pipeline);
|
|
```
|
|
|
|
At this point you can use `client` like every Client from `package:http/http.dart` .
|
|
|
|
## Recipes
|
|
|
|
### Rest API with URL Authentication
|
|
|
|
Let's build a client for a REST API where the (bad) authentication is through the URL.
|
|
We need some middlewares:
|
|
|
|
* SimpleLogger, to log every request and response (useful for debug).
|
|
* BodyToJson, to automaticaly transform Map object to JSON.
|
|
* UriPrefix, to simplify the build of an API Object (save protocol and API prefix).
|
|
* UnsafeAuth, to use url based authentication.
|
|
|
|
Let's start by creating the Pipeline:
|
|
|
|
```dart
|
|
final Pipeline pipeline = Pipeline()
|
|
.addMiddleware(
|
|
UriPrefixMiddleware(
|
|
protocol: Protocols.http,
|
|
authority: 'localhost:80',
|
|
),
|
|
)
|
|
.addMiddleware(BodyToJsonMiddleware())
|
|
.addMiddleware(
|
|
UnsafeAuthMiddleware(
|
|
username: 'wyatt',
|
|
password: 'motdepasse',
|
|
),
|
|
)
|
|
.addMiddleware(SimpleLoggerMiddleware());
|
|
```
|
|
|
|
Then simply create a client and make a call.
|
|
|
|
```dart
|
|
final client = MiddlewareClient(pipeline: pipeline);
|
|
|
|
await client.get(Uri.parse('/protected'));
|
|
```
|
|
|
|
> Here it make a `GET` call on `http://localhost:80/protected?username=wyatt&password=motdepasse`
|
|
|
|
And voilà.
|
|
|
|
### Rest API with Oauth2
|
|
|
|
So now we want a real authentication.
|
|
|
|
```dart
|
|
final Pipeline pipeline = Pipeline()
|
|
.addMiddleware(
|
|
UriPrefixMiddleware(
|
|
protocol: Protocols.http,
|
|
authority: 'localhost:80',
|
|
),
|
|
)
|
|
.addMiddleware(BodyToJsonMiddleware())
|
|
.addMiddleware(
|
|
RefreshTokenAuthMiddleware(
|
|
authorizationEndpoint: '/auth/sign-in',
|
|
tokenEndpoint: '/auth/refresh',
|
|
accessTokenParser: (body) => body['access_token']! as String,
|
|
refreshTokenParser: (body) => body['refresh_token']! as String,
|
|
unauthorized: HttpStatus.forbidden,
|
|
),
|
|
)
|
|
.addMiddleware(SimpleLoggerMiddleware());
|
|
```
|
|
|
|
> Here we just change `UnsafeAuthMiddleware` by `RefreshTokenAuthMiddleware` and the whole app while adapt to a new authentication system.
|
|
|
|
### Create a new Middleware
|
|
|
|
You can create your own middleware by implementing `Middleware` class, and use mixins to add `OnRequest` and/or `OnResponse` methods.
|
|
|
|
```dart
|
|
class SimpleLoggerMiddleware
|
|
with OnRequestMiddleware, OnResponseMiddleware
|
|
implements Middleware {
|
|
|
|
@override
|
|
String getName() => 'SimpleLogger';
|
|
|
|
@override
|
|
Future<MiddlewareRequest> onRequest(
|
|
MiddlewareContext context,
|
|
MiddlewareRequest request,
|
|
) async {
|
|
print('${getName()}::OnRequest');
|
|
return request;
|
|
}
|
|
|
|
@override
|
|
Future<MiddlewareResponse> onResponse(
|
|
MiddlewareContext context,
|
|
MiddlewareResponse response,
|
|
) async {
|
|
print('${getName()}::OnResponse');
|
|
return response;
|
|
}
|
|
}
|
|
```
|