美文网首页DartVM服务器开发Flutter圈子Flutter中文社区
DartVM服务器开发(第二十二天)--RestfulApi封装

DartVM服务器开发(第二十二天)--RestfulApi封装

作者: rhyme_lph | 来源:发表于2018-09-11 18:08 被阅读21次

    上一篇,我们讲解了如何使用jaguar_serializer,今天,我们来学习一下如何通过该package,并结合之前的东西,封装起RestfulApi,该封装同样也适合Flutter,dart web

    阅读该文章之前,我会默认的认为你已经看过我之前的文章,并知道如何使用数据库,开启服务器等!


    图片来自网络.jpg

    1.定义规范

    • 资源
      使用JSON的形式表现
    • 资源格式
      code 表示状态,0表示处理成功,-1表示处理失败
      msg 表示消息,对客户端需要说明的一些信息,如:成功,请求方法不允许
      data表示数据,返回客户端的数据
    • 接口
      get获取资源,查询资源
      post新建资源,更新资源,查询资源
      put更新资源
      delete删除资源
    • URI
      请求的地址可以附带id等,例如: Get http://localhost:8080/user/123 查询id为123的用户,Get http://localhost/user 查询所有用户, Post http://localhost:8080/user/123 修改id为123的的用户等

    2. 定义Restful

    我们新建一个Restful文件,输入下面代码

    class Restful {
      int code;
      String msg;
      Object data;
    }
    

    然后导入jaguar_serializer包,添加下面代码

    @GenSerializer()
    class RestfulSerializer extends Serializer<Restful> with _$RestfulSerializer {}
    

    运行命令pub run build_runner build,完后继续添加

    part 'Restful.jser.dart';
    

    ok,我们已经准备好Restful,那怎么把数据放到data里面呢
    我们先来创建一个user.dart文件,创建一个用户模型,

    class User {
      String id;
      String username;
      String password;
      int role;
      String phoneNumber;
      int sex;
    }
    

    与数据库进行关联

    import 'package:jaguar_orm/jaguar_orm.dart';
    import 'dart:async';
    part 'user.jorm.dart';
    class User {
      @PrimaryKey()
      String id;
      String username;
      String password;
      int role;
      @Column(length: 11)
      String phoneNumber;
      int sex;
      static const String tableName='_user';
      @override
        String toString()=> 'User(id:$id,username:$username,password:$password,role:$role,phoneNumber:$phoneNumber,sex:$sex)';
    }
    @GenBean()
    class UserBean extends Bean<User> with _UserBean {
      UserBean(Adapter adapter) : super(adapter);
      @override
      String get tableName => User.tableName;
    }
    

    创建一个serializer.dart文件,用于存放所有json_serializer工具文件,添加下面代码

    import 'package:jaguar_serializer/jaguar_serializer.dart';
    import 'user.dart';
    part 'serializer.jser.dart';
    @GenSerializer()
    class UserSerializer extends Serializer<User> with _$UserSerializer {
    }
    

    运行pub run build_runner build命令
    下面是打印一个通过数据库查询id为2的restful api返回数据

    import 'package:jaguar_query_postgres/jaguar_query_postgres.dart';
    import 'package:TestDB/user.dart';
    import 'package:TestDB/Restful.dart';
    import 'package:TestDB/serializer.dart';
    import 'dart:convert';
    final PgAdapter pgAdapter =
        new PgAdapter('postgres', username: 'postgres', password: '123456');
    
    main() async {
      await pgAdapter.connect();
      Restful restful = new Restful()
        ..code = 0
        ..msg = 'success'
        ..data = new UserSerializer().toMap((await new UserBean(pgAdapter).find("2")));
      print(json.encode(new RestfulSerializer().toMap(restful)));
    }
    

    我们可以简单的知道,一个模型转换为json数据需要经过两步操作

    • 模型转换为Map
    • map经过 json.encode 编码为字符串

    相反的,json数据转换为模型也是两步

    • 字符串经过json.decode译码为map
    • map转换为模型
      所以,我们可以结合jaguar_serializer封装一下Restful,封装如下
    import 'dart:convert';
    import 'package:jaguar_serializer/jaguar_serializer.dart';
    part 'Restful.jser.dart';
    RestfulSerializer serializer = new RestfulSerializer();
    class Restful {
      int code;
      String msg;
      Object data;
      Restful();
      Map toMap([Serializer dataSerializer]) {
        if(dataSerializer==null){
          return serializer.toMap(this);
        }
        if (data is List) {
          List list =data;
          if(list.length!=0&& list[0] is Map){
          }else if(list.length!=0){
          data = dataSerializer.toList(data);
          }
        } else if (data is Map) {
        } else {
          data = dataSerializer.toMap(data);
        }
        return serializer.toMap(this);
      }
    
      String toJson([Serializer dataSerializer]) {
        return json.encode(toMap(dataSerializer));
      }
    
      factory Restful.fromMap(Map<String,dynamic> map, [Serializer dataSerializer]) {
        Restful api = serializer.fromMap(map);
    
        if(dataSerializer==null){
          return api;
        }
        if (api.data is List) {
           List<Map<dynamic,dynamic>> data=(api.data as List<dynamic>).map((d)=>d as Map<dynamic,dynamic>).toList();
          api.data = dataSerializer.fromList(data);
        } else if (api.data == null) {
        } else {
          api.data = dataSerializer.fromMap(api.data);
        }
        return api;
      }
    
      factory Restful.fromJson(String Json, [Serializer dataSerializer]) {
        return new Restful.fromMap(json.decode(Json),dataSerializer);
      }
    
      T fromJsonToData<T>(String Json,Serializer dataSerializer) {
        Restful api = serializer.fromMap(json.decode(Json));
        if (api.data is List) {
          // throw ArgumentError('data is List');
          return null;
        } else if (api.data == null) {
          return null;
        } else {
          return dataSerializer.fromMap(api.data);
        }
      }
    
      List<T> fromJsonToListData<T>(String Json, [Serializer dataSerializer]) {
        Restful restful = new Restful.fromJson(Json, dataSerializer);
        if (restful.data is List) {
          if(dataSerializer==null){
          return restful.data;
        }
          return restful.data;
        } else if (restful.data == null) {
          return null;
        } else {
          return null;
        }
      }
    }
    @GenSerializer()
    class RestfulSerializer extends Serializer<Restful> with _$RestfulSerializer {}
    

    上面主要有6个方法

    • toMap([Serializer dataSerializer])Restful转换为map,传入的是data对应的类型序列化工具[]表示非必填,如果data是基本类型,可不填
    • toJson([Serializer dataSerializer])Restful转换为字符串
    • Restful.fromMap(Map<String,dynamic> map, [Serializer dataSerializer])map转换为Restful
    • Restful.fromJson(String Json, [Serializer dataSerializer])字符串转换为Restful
    • fromJsonToData<T>(String Json,Serializer dataSerializer)字符串直接转换为data(T为泛型)
    • fromJsonToListData<T>(String Json, [Serializer dataSerializer])字符串直接转换为List<T>

    3.定制接口

    工具已经有了,数据也有了,那么我们现在就开始着手写接口了
    main.dart

    import 'package:jaguar_query_postgres/jaguar_query_postgres.dart';
    import 'package:jaguar/jaguar.dart';
    import 'package:jaguar_reflect/jaguar_reflect.dart';
    import 'package:TestDB/UserController.dart';
    final PgAdapter pgAdapter =
        new PgAdapter('postgres', username: 'postgres', password: '123456');
    
    main() async {
      await pgAdapter.connect();
      new Jaguar( port: 1000)
      ..add(reflect(new UserController(pgAdapter)))
      ..serve();
    }
    

    UserController.dart

    import 'package:jaguar/jaguar.dart';
    import 'package:jaguar_orm/jaguar_orm.dart';
    import 'serializer.dart';
    import 'Restful.dart';
    import 'user.dart';
     @Controller(path: '/user')
     class UserController {
       final UserBean userBean;
       UserController(Adapter adapter):userBean=new UserBean(adapter);
       @Get( path: '/:id')
        user(Context ctx) async{
          String id=ctx.pathParams['id'];
          Restful restful=new Restful()
          ..code=0
          ..msg='success'
          ..data=await userBean.find(id);
          return Response.json( restful.toMap(new  UserSerializer()));
       }
     }
    

    我们来请求一下数据看看http://localhost:1000/user/1

    user.png
    可以看到,我们成功的在数据库中查找到一条记录,然后以json的形式传递给客户端
    下面就是写其他的增删查改接口了
    import 'package:jaguar/jaguar.dart';
    import 'package:jaguar_orm/jaguar_orm.dart';
    import 'serializer.dart';
    import 'Restful.dart';
    import 'user.dart';
     @Controller(path: '/user')
     class UserController {
       final UserBean userBean;
    
       UserController(Adapter adapter):userBean=new UserBean(adapter);
       
       @Get( path: '/:id')
        user(Context ctx) async{
          String id=ctx.pathParams['id'];
          Restful restful=new Restful()
          ..code=0
          ..msg='success'
          ..data=await userBean.find(id);
          return Response.json( restful.toMap(new  UserSerializer()));
       }
    
       @Post(path: '/:id')
       userEdit(Context ctx) async{
         String id=ctx.pathParams['id'];
         User user=await ctx.bodyAsJson(convert: new UserSerializer().fromMap);
         user.id=id;
         await userBean.update(user);
         return Response.json((new Restful()
         ..code=0
         ..msg='ok').toMap());
       }
    
        @Put(path: '/')
        userAdd(Context ctx) async{
         User user=await ctx.bodyAsJson(convert: new UserSerializer().fromMap);
          await userBean.insert(user);
          return Response.json((new Restful()
         ..code=0
         ..msg='ok').toMap());
        }
    
        @Delete(path: '/:id')
        userDelete(Context ctx) async{
         String id=ctx.pathParams['id'];
          await userBean.remove(id);
          return Response.json((new Restful()
         ..code=0
         ..msg='ok').toMap());
        }
     }
    

    ok,上面就是今天的全部内容,我们明天见!

    如果想继续学习DartVM服务器开发,请关注我,学习更多骚操作!

    相关文章

      网友评论

      • 文丞:期待更新
      • LanceAdd:就很喜欢这种直白的路由写法,和flask很像

      本文标题:DartVM服务器开发(第二十二天)--RestfulApi封装

      本文链接:https://www.haomeiwen.com/subject/krtugftx.html