Uno
Dart和Flutter的基于Future的HTTP客户端。
Uno受Axios启发,为
Flutter中的跨平台应用和Dart中的服务器应用带来了简单而强大的体验。
安装
添加到您的pubspec.yaml
dependencies:
uno: <last-version>
或使用
dart pub add uno
用法
Uno已准备好处理REST。GET、POST、PUT、PATCH、DELETE等方法都欢迎在此使用!
执行GET请求
final uno = Uno();
// Make a request for a user with a given ID
uno.get('/users?id=1').then((response){
print(response.data); // it's a Map<String, dynamic>.
}).catchError((error){
print(error) // It's a UnoError.
});
// Optionally the request above could also be done as
uno.get('/users',params: {
'id': '1',
}).then((response){
print(response.data);
});
// Want to use async/await? Add the `async` keyword to your outer function/method.
Future<void> getUser() async {
try {
final response = await uno.get('/user?ID=12345');
print(response.data;
} on UnoError catch (error) {
print(error);
}
}
执行POST请求
uno.post('/user', data: {
'firstName': 'Fred',
'lastName': 'Flintstone'
})
.then((response) {
print(response);
})
.catchError((error) {
print(error);
});
Uno API
可以通过将相关配置传递给Uno来发出请求。
// Send a POST request
uno(
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
},
);
// Download image from server;
uno(
method: 'get',
url: 'http://bit.ly/2mTM3nY',
responseType: ResponseType.arraybuffer,
onDownloadProgress: (total, current) {
final percentCompleted = (current / total * 100).round();
print('completed: $percentCompleted%');
},
).then((response) async {
await File('ada_lovelace.jpg').writeAsBytes(response.data);
});
创建实例
final uno = Uno(
baseURL: 'https://some-domain.com/api/',
timeout: Duration(second: 30),
headers: {'X-Custom-Header': 'foobar'}
);
拦截器
您可以在处理then或catch之前拦截请求或响应。
// Add a request interceptor
uno.interceptors.request.use((request) {
// Do something before request is sent
return request;
}, onError: (error) {
// Do something with request error
return error;
});
// Add a response interceptor
uno.interceptors.response.use((response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, onError: (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return error;
});
如果您以后需要删除拦截器,可以这样做。
final myInterceptor = uno.interceptors.request.use((request) {/*...*/});
uno.interceptors.request.eject(myInterceptor);
如果您想根据运行时检查来执行特定拦截器,可以在选项对象中添加`runWhen`函数。如果`runWhen`的返回值为false,则不会执行拦截器。该函数将接收配置对象(别忘了您也可以为其绑定自己的参数)。当您有一个仅在特定时间运行的异步请求拦截器时,这会很有用。
bool onGetCall(request) {
return request.method == 'get';
}
uno.interceptors.request.use((request) {
request.headers['test'] = 'special get headers';
return request;
}, runWhen: onGetCall);
处理错误
uno.get('/user/12345')
.catchError((error) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
print(error.response.data);
print(error.response.status);
print(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
print(error.request);
} else {
// Something happened in setting up the request that triggered an Error
print('Error ${error.message}');
}
});
使用`validateStatus`配置选项,您可以定义应该抛出错误的HTTP代码。
axios.get('/user/12345', {
validateStatus: (status) {
return status < 500; // Resolve only if the status code is less than 500
}
});
Multipart/FormData
您可以使用`form-data`
final form = FormData();
form.add('my_field', 'my value');
form.addBytes('my_buffer', <int>[]);
form.addFile('my_file', 'my_file.pdf');
uno.post('https://example.com', data: form);
功能和 Bug
请在问题跟踪器上提交功能请求和错误。