Fluent news client – 04 Yapi interface management, restful, code generation, DIO encapsulation

Time:2021-10-17

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

Station B video

https://www.bilibili.com/vide…

Objectives of this section

  • Front end separation and contract development mode
  • API interface management and tools
  • Restful interface specification
  • Token security communication
  • Automatically generate entity interface entity class
  • Dio package
  • Localstorage local storage
  • Password encryption

1. Interface management

1.1 front and rear end separation and contract mode

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

1.2 common interface management tools

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

1.3 Yapi interface management tool (recommended by brother cat)

http://yapi.demo.qunar.com/

  • input

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

  • output

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

1.4 mock simulation data

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

1.5 unit test

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

1.6 swagger import

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

2. Restful interface style

2.1 HTTP operation mode

  • Get fetch data
  • Post new data
  • Put updates all data
  • Patch updates some data
  • Delete delete data

example:

Get / zoos: list all zoos
Post / zoos: create a new zoo
Get / zoos / ID: get the information of a specified zoo
Put / zoos / ID: update the information of a designated Zoo (provide all the information of the zoo)
Patch / zoos / ID: update the information of a specified Zoo (provide some information of the zoo)
Delete / zoos / ID: delete a zoo
Get / zoos / ID / animals: lists all animals in a specified zoo
Delete / zoos / ID / animals / ID: deletes the specified animals in a specified zoo

2.2 state control

  • 200 OK
  • 400 wrong requests, such as incorrect data structure
  • 401 login authentication required
  • 403 logged in, but the current resource is not authorized
  • 404 not found, wrong address
  • 500 service program error
  • 502 service gateway error
  • 503 service hung up
  • 504 service gateway timeout

2.3 excellent practice

3. Token security communication

3.1 token based security mechanism

  • technological process

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

  • thinking

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

3.2 Bearer Type Access Token

Add in the communication HTTP header

GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

3.3 JWT

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

4. Automatically generate entity

4.1 json_ Serializable (official)

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

4.2 JSON to code

Fluent news client - 04 Yapi interface management, restful, code generation, DIO encapsulation

  • Vscode plugin

https://marketplace.visualstu…

5. DIO package

5.1 singleton mode

  • dio

https://pub.dev/packages/dio

  • lib/common/utils/http.dart

Common packaging methods of single case

class HttpUtil {
  static HttpUtil _instance = HttpUtil._internal();
  factory HttpUtil() => _instance;

  Dio dio;
  CancelToken cancelToken = new CancelToken();

  HttpUtil._internal() {
    ...

5.2 maintaining tokens

Read from local storage

  • localstorage

https://pub.flutter-io.cn/pac…

  • getLocalOptions()
  Options getLocalOptions() {
    Options options;
    String token = StorageUtil().getItem(STORAGE_USER_TOKEN_KEY);
    if (token != null) {
      options = Options(headers: {
        'Authorization': 'Bearer $token',
      });
    }
    return options;
  }

5.3 handling exceptions

Formatting, error messages, differential treatment

  • createErrorEntity()
ErrorEntity createErrorEntity(DioError error) {
    switch (error.type) {
      case DioErrorType.CANCEL:
        {
          Return errorentity (Code: - 1, message: "request cancellation");
        }
        break;
      case DioErrorType.CONNECT_TIMEOUT:
        {
          Return errorentity (Code: - 1, message: "connection timeout");
        }
        break;
      case DioErrorType.SEND_TIMEOUT:
        {
          Return errorentity (Code: - 1, message: "request timeout");
        }
        break;
      case DioErrorType.RECEIVE_TIMEOUT:
        {
          Return errorentity (Code: - 1, message: "response timeout");
        }
        break;
      case DioErrorType.RESPONSE:
        {
          try {
            int errCode = error.response.statusCode;
            // String errMsg = error.response.statusMessage;
            // return ErrorEntity(code: errCode, message: errMsg);
            switch (errCode) {
              case 400:
                {
                  Return errorentity (Code: errCode, message: "request syntax error");
                }
                break;
              case 401:
                {
                  Return errorentity (Code: errCode, message: "no permission");
                }
                break;
              case 403:
                {
                  Return errorentity (Code: errCode, message: "the server refused to execute");
                }
                break;
              case 404:
                {
                  Return errorentity (Code: errCode, message: "unable to connect to the server");
                }
                break;
              case 405:
                {
                  Return errorentity (Code: errCode, message: "the request method is prohibited");
                }
                break;
              case 500:
                {
                  Return errorentity (Code: errCode, message: "server internal error");
                }
                break;
              case 502:
                {
                  Return errorentity (Code: errCode, message: "invalid request");
                }
                break;
              case 503:
                {
                  Return errorentity (Code: errCode, message: "the server hangs up");
                }
                break;
              case 505:
                {
                  Return errorentity (Code: errCode, message: "HTTP protocol request is not supported");
                }
                break;
              default:
                {
                  //Return errorentity (Code: errCode, message: "unknown error");
                  return ErrorEntity(
                      code: errCode, message: error.response.statusMessage);
                }
            }
          } on Exception catch (_) {
            Return errorentity (Code: - 1, message: "unknown error");
          }
        }
        break;
      default:
        {
          return ErrorEntity(code: -1, message: error.message);
        }
    }
  }

6. Login call

6.1 writing API interface

  • lib/common/apis/user.dart
import 'package:flutter_ducafecat_news/common/entitys/entitys.dart';
import 'package:flutter_ducafecat_news/common/utils/utils.dart';

///User
class UserAPI {
  ///Login
  static Future<UserResponseEntity> login({UserRequestEntity params}) async {
    var response = await HttpUtil().post('/user/login', params: params);
    return UserResponseEntity.fromJson(response);
  }
}

6.2 password encryption

  • crypto

https://pub.dev/packages/crypto

  • lib/common/utils/security.dart
import 'dart:convert';
import 'package:crypto/crypto.dart';

/// SHA256
String duSHA256(String input) {
  String salt = ' [email protected] @X#qn17! StJNdZK1fFF8iV6ffN! goZkqt#JxO'; //  Add salt
  var bytes = utf8.encode(input + salt);
  var digest = sha256.convert(bytes);

  return digest.toString();
}

6.3 calling interface

  • lib/pages/sign_in/sign_in.dart
//Perform login operation
  _handleSignIn() async {
    if (!duIsEmail(_emailController.value.text)) {
      Toastinfo (MSG: 'please input mail correctly');
      return;
    }
    if (!duCheckStringLength(_passController.value.text, 6)) {
      Toastinfo (MSG: 'password cannot be less than 6 digits');
      return;
    }

    UserRequestEntity params = UserRequestEntity(
      email: _emailController.value.text,
      password: duSHA256(_passController.value.text),
    );

    UserResponseEntity res = await UserAPI.login(params: params);

    //Write local access_ Token, do not write global, business: offline login
    //Global data guser
  }

Yapi interface management

http://yapi.demo.qunar.com/

Git code

https://github.com/ducafecat/…

Blue lake design draft

https://lanhuapp.com/url/lYuz1
Password: gskl

Blue lake charges now, so please upload XD design draft by yourself to view the tag
It’s difficult to share the commercial design documents directly. You can contact ducafecat through wechat

reference resources

video