DartVM服務器開發(fā)(第二十二天)--RestfulApi封裝

上一篇藕畔,我們講解了如何使用jaguar_serializer,今天变汪,我們來學習一下如何通過該package,并結(jié)合之前的東西,封裝起RestfulApi碱妆,該封裝同樣也適合Flutter,dart web

閱讀該文章之前辛馆,我會默認的認為你已經(jīng)看過我之前的文章,并知道如何使用數(shù)據(jù)庫百宇,開啟服務器等考廉!


圖片來自網(wǎng)絡.jpg

1.定義規(guī)范

  • 資源
    使用JSON的形式表現(xiàn)
  • 資源格式
    code 表示狀態(tài),0表示處理成功,-1表示處理失敗
    msg 表示消息携御,對客戶端需要說明的一些信息昌粤,如:成功,請求方法不允許
    data表示數(shù)據(jù),返回客戶端的數(shù)據(jù)
  • 接口
    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,完后繼續(xù)添加

part 'Restful.jser.dart';

ok谭企,我們已經(jīng)準備好Restful廓译,那怎么把數(shù)據(jù)放到data里面呢
我們先來創(chuàng)建一個user.dart文件评肆,創(chuàng)建一個用戶模型,

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

與數(shù)據(jù)庫進行關聯(lián)

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

創(chuàng)建一個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命令
下面是打印一個通過數(shù)據(jù)庫查詢id為2的restful api返回數(shù)據(jù)

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

我們可以簡單的知道瓜挽,一個模型轉(zhuǎn)換為json數(shù)據(jù)需要經(jīng)過兩步操作

  • 模型轉(zhuǎn)換為Map
  • map經(jīng)過 json.encode 編碼為字符串

相反的,json數(shù)據(jù)轉(zhuǎn)換為模型也是兩步

  • 字符串經(jīng)過json.decode譯碼為map
  • map轉(zhuǎn)換為模型
    所以征绸,我們可以結(jié)合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轉(zhuǎn)換為map,傳入的是data對應的類型序列化工具[]表示非必填管怠,如果data是基本類型淆衷,可不填
  • toJson([Serializer dataSerializer])Restful轉(zhuǎn)換為字符串
  • Restful.fromMap(Map<String,dynamic> map, [Serializer dataSerializer])map轉(zhuǎn)換為Restful
  • Restful.fromJson(String Json, [Serializer dataSerializer])字符串轉(zhuǎn)換為Restful
  • fromJsonToData<T>(String Json,Serializer dataSerializer)字符串直接轉(zhuǎn)換為data(T為泛型)
  • fromJsonToListData<T>(String Json, [Serializer dataSerializer])字符串直接轉(zhuǎn)換為List<T>

3.定制接口

工具已經(jīng)有了,數(shù)據(jù)也有了渤弛,那么我們現(xiàn)在就開始著手寫接口了
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()));
   }
 }

我們來請求一下數(shù)據(jù)看看http://localhost:1000/user/1

user.png

可以看到祝拯,我們成功的在數(shù)據(jù)庫中查找到一條記錄,然后以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,上面就是今天的全部內(nèi)容她肯,我們明天見!

如果想繼續(xù)學習DartVM服務器開發(fā)佳头,請關注我,學習更多騷操作晴氨!

下一篇:DartVM服務器開發(fā)(第二十三天)--緩存層(jaguar_cache)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末康嘉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子籽前,更是在濱河造成了極大的恐慌亭珍,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枝哄,死亡現(xiàn)場離奇詭異肄梨,居然都是意外死亡,警方通過查閱死者的電腦和手機膘格,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來财松,“玉大人瘪贱,你說我怎么就攤上這事×菊保” “怎么了菜秦?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舶掖。 經(jīng)常有香客問我球昨,道長,這世上最難降的妖魔是什么眨攘? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任主慰,我火速辦了婚禮嚣州,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘共螺。我一直安慰自己该肴,他們只是感情好,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布藐不。 她就那樣靜靜地躺著匀哄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雏蛮。 梳的紋絲不亂的頭發(fā)上涎嚼,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機與錄音挑秉,去河邊找鬼法梯。 笑死,一個胖子當著我的面吹牛衷模,可吹牛的內(nèi)容都是我干的鹊汛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼阱冶,長吁一口氣:“原來是場噩夢啊……” “哼刁憋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起木蹬,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤至耻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后镊叁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尘颓,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年晦譬,在試婚紗的時候發(fā)現(xiàn)自己被綠了疤苹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡敛腌,死狀恐怖卧土,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情像樊,我是刑警寧澤尤莺,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站生棍,受9級特大地震影響颤霎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一友酱、第九天 我趴在偏房一處隱蔽的房頂上張望晴音。 院中可真熱鬧,春花似錦粹污、人聲如沸段多。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽进苍。三九已至,卻和暖如春鸭叙,著一層夾襖步出監(jiān)牢的瞬間觉啊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工沈贝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杠人,地道東北人。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓宋下,卻偏偏與公主長得像嗡善,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子学歧,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345