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'}
);

拦截器

您可以在处理thencatch之前拦截请求或响应。

  // 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

请在问题跟踪器上提交功能请求和错误。

GitHub

查看 Github