-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
3302 lines (3299 loc) · 482 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-CN">
<id>https://umajs.github.io/</id>
<title>UMajs</title>
<subtitle>Umajs,an easy-to-use NodeJS framework base on Typescript.</subtitle>
<updated>2023-03-17T10:19:56.314Z</updated>
<generator>vuepress-plugin-feed2</generator>
<link rel="self" href="https://umajs.github.io/atom.xml"/>
<link rel="alternate" href="https://umajs.github.io/"/>
<entry>
<title type="html">面向切面(AOP)</title>
<id>https://umajs.github.io/development/AOP.html</id>
<link href="https://umajs.github.io/development/AOP.html"/>
<updated>2023-03-17T10:20:25.146Z</updated>
<content type="html"><![CDATA[<h1 id="面向切面-aop" tabindex="-1"> 面向切面(AOP)</h1>
<p>AOP(Aspect Oriented Programming)面向切面编程是与 OOP(Object Oriented Programming)面向对象编程并列的编程思想。相对于 IOC(依赖注入)而言,AOP 是一种可以在不修改源代码的情况下给程序动态添加功能的一种方式。</p>
<p>使用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。</p>
<h2 id="什么是切面-aspect" tabindex="-1"> 什么是切面(Aspect)</h2>
<p>AOP 称为<code>面向切面编程</code>,所以切面(Aspect)是 AOP 中一个很关键的点。</p>
<p>假设我们有一个订单系统,有如下两条线的功能,提交订单和查询订单,每个事件流都需要执行“验证用户信息”的操作,将这个功能框起来后,你可以把它当块板子,这块板子插入了一些控制流程,这块板子就可以当成是 AOP 中的一个切面。</p>
<p><img src="@source/../public/images/AOP-aspect.png" alt="AOP"></p>
<h2 id="通知" tabindex="-1"> 通知</h2>
<p><code>通知</code>是 AOP 中一个很重要的概念,所谓通知指的就是在拦截到方法之后要执行的代码。通知分为前置(before)、后置(after)、异常(afterThrowing)、最终(afterReturning)、环绕(around)通知五类。</p>
<ul>
<li>前置通知:在目标方法之前执行</li>
<li>后置通知:在目标方法之后执行</li>
<li>异常通知:当执行目标方法出现异常时执行</li>
<li>最终通知:当目标方法有返回值之后执行,在后置通知之后</li>
<li>环绕通知:在最开始调用时执行,会将目标方法作为参数传入,对目标方法(proceed)及入参(args)、出参(result)进行拦截,此方法必须返回 Result</li>
</ul>
<blockquote>
<p>在 Uma 的 V1 版本我们实现了5个通知,在 V2 版本我们对通知进行了简化,减少用户对 AOP 理解的成本,保留了使用最多最灵活的 环绕<code>around</code>通知</p>
</blockquote>
<h2 id="around修饰器" tabindex="-1"> @Around修饰器</h2>
<p>在 Uma 中,可以通过修饰器<code>@Around</code>的方式为方法添加环绕通知,Around修饰器接收一个参数,作为通知方法</p>
<h3 id="类型声明" tabindex="-1"> 类型声明</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">/**</span></span>
<span><span style="color: #8B949E"> * </span><span style="color: #FF7B72">@param</span><span style="color: #8B949E"> </span><span style="color: #C9D1D9">around</span><span style="color: #8B949E"> 要执行的通知方法,方法需要return Uma 提供的 Result结果</span></span>
<span><span style="color: #8B949E"> */</span></span>
<span><span style="color: #D2A8FF">Around</span><span style="color: #C9D1D9">(around: (</span><span style="color: #FFA657">point</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">IProceedJoinPoint</span><span style="color: #C9D1D9">) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">Promise</span><span style="color: #FF7B72"><</span><span style="color: #C9D1D9">Result</span><span style="color: #FF7B72"><</span><span style="color: #C9D1D9">any</span><span style="color: #FF7B72">>></span><span style="color: #C9D1D9">)</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br></div></div><h3 id="示例" tabindex="-1"> 示例</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Result, Around } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span><span style="color: #C9D1D9">;</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { method } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'../aspect/method.aspect'</span><span style="color: #C9D1D9">;</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Index </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #8B949E">// 为index方法添加around修饰,method为对应要执行的around通知方法</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Around</span><span style="color: #FFA657">(</span><span style="color: #C9D1D9">method</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'ok'</span><span style="color: #C9D1D9">);</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br></div></div><div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// /aspect/method.aspect.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { IProceedJoinPoint } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span><span style="color: #C9D1D9">;</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">async</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">function</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">method</span><span style="color: #C9D1D9">(</span><span style="color: #FFA657">proceedPoint</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">IProceedJoinPoint</span><span style="color: #C9D1D9"><</span><span style="color: #79C0FF">any</span><span style="color: #C9D1D9">>) {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 执行around before方法,即在被修饰方法执行前操作,当做一些前置校验的时候如果不满足可以直接return</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">log</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is around'</span><span style="color: #C9D1D9">);</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 执行被修饰的方法</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">result</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">await</span><span style="color: #C9D1D9"> proceedPoint.</span><span style="color: #D2A8FF">proceed</span><span style="color: #C9D1D9">();</span></span>
<span><span style="color: #C9D1D9"> </span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 执行around after方法,即在被修饰方法执行后操作</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">log</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is around after'</span><span style="color: #C9D1D9">);</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> result;</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br><span>14</span><br><span>15</span><br></div></div><h3 id="middlewaretoaround" tabindex="-1"> middlewareToAround</h3>
<p>Uma 提供了将<code>Middleware(中间件)转Around(环绕)</code>的方法<code>middlewareToAround</code>,将中间件转为 Around 修饰器后,我们可以以 AOP 的装饰器形式使用中间件。 在V2版本之后,我们可以直接使用@Middleware修饰器直接将koa中间件作用于方法。具体参考 <a href="/development/Middleware.html#aop-%E8%A3%85%E9%A5%B0%E5%99%A8%E5%BD%A2%E5%BC%8F">Middleware 参考文档</a></p>
]]></content>
</entry>
<entry>
<title type="html">配置(Config)</title>
<id>https://umajs.github.io/development/Config.html</id>
<link href="https://umajs.github.io/development/Config.html"/>
<updated>2023-03-17T10:20:25.146Z</updated>
<content type="html"><![CDATA[<h1 id="配置-config" tabindex="-1"> 配置(Config)</h1>
<h2 id="config-loader" tabindex="-1"> config loader</h2>
<p>Uma 的配置通过自动合并 app 及框架的配置,并根据不同环境读取不同的配置,最终配置通过<code>Uma.config</code>获取。</p>
<blockquote>
<p>插件的配置的 <code>options</code> 最终会和对应名称的 <code>config</code>(*.config.ts) 合并后传给插件</p>
<p><code>config</code> 的优先级最高,会将 <code>options</code> 中相同的配置覆盖、不同的合并</p>
</blockquote>
<h3 id="配置目录" tabindex="-1"> 配置目录</h3>
<p>框架默认会加载<code>${URSA_ROOT}/config</code>目录下以<code>xx.config.xx</code>命名的配置文件</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #c9d1d9">|- config
|- plugin.config.ts
</span></span></code></pre><div><span>1</span><br><span>2</span><br></div></div><p>你也可以根据需求在实例化时通过<code>configPath</code>来指定配置目录</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">uma</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> Uma.</span><span style="color: #D2A8FF">instance</span><span style="color: #C9D1D9">({</span></span>
<span><span style="color: #C9D1D9"> Router,</span></span>
<span><span style="color: #C9D1D9"> ROOT: __dirname,</span></span>
<span><span style="color: #C9D1D9"> configPath: path.</span><span style="color: #D2A8FF">join</span><span style="color: #C9D1D9">(__dirname, </span><span style="color: #A5D6FF">'defaultConfig'</span><span style="color: #C9D1D9">),</span></span>
<span><span style="color: #C9D1D9">})</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br></div></div><h3 id="cli-初始化配置" tabindex="-1"> cli 初始化配置</h3>
<p>通过 <code>uma</code> 命令可以快速的给工程添加插件或者可发布的插件工程</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9">uma config init [configName]</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="配置获取" tabindex="-1"> 配置获取</h3>
<p><code>xx.config.ts</code>需 export 一个 default 值,配置将以文件名为 key,default 值为 value 存在实例上,可以通过<code>Uma</code>的 config 属性来获取到所有 config 值</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9">Uma.config </span><span style="color: #8B949E">// 获取 config 所有数据</span></span>
<span><span style="color: #C9D1D9">Uma.config.status </span><span style="color: #8B949E">// 获取 status 配置</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br></div></div>]]></content>
</entry>
<entry>
<title type="html">控制器(Controller)</title>
<id>https://umajs.github.io/development/Controller.html</id>
<link href="https://umajs.github.io/development/Controller.html"/>
<updated>2023-03-17T10:20:25.146Z</updated>
<content type="html"><![CDATA[<h1 id="控制器-controller" tabindex="-1"> 控制器(Controller)</h1>
<h2 id="什么是控制器" tabindex="-1"> 什么是控制器</h2>
<p>控制器负责解析用户输入,并向用户返回处理结果。</p>
<p>在控制器中,我们可以指定什么时候(<strong>路由</strong>)去响应,怎么样(<strong>服务</strong>)去返回结果。</p>
<h2 id="控制器加载与编写" tabindex="-1"> 控制器加载与编写</h2>
<h3 id="加载" tabindex="-1"> 加载</h3>
<p>控制器也是通过约定的策略进行加载:默认加载<code>${URSA_ROOT}/controller</code>下所有<code>*.controller</code>文件。</p>
<h3 id="控制器编写" tabindex="-1"> 控制器编写</h3>
<p><code>Uma</code>的控制器需要通过类的继承的方式实现,方法必须都返回框架内置的 Result 静态方法,如下代码</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Index </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 等同于 return Result.send('this is index router');</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br></div></div><p>命中路由规则的控制器,在请求时会被实例化,以下属性可以通过<code>this</code>获取:</p>
<ol>
<li><code>ctx</code>: 当前请求上下文</li>
<li><code>req</code>: <code>Request</code>实例</li>
<li><code>res</code>: <code>Response</code>实例</li>
</ol>
<h2 id="获取请求参数" tabindex="-1"> 获取请求参数</h2>
<h3 id="query-和路由参数" tabindex="-1"> query 和路由参数</h3>
<p>详见 Router#@Param、@Query 修饰器</p>
<h3 id="header" tabindex="-1"> header</h3>
<p>获取 header 参数可以用<code>this.header(name)</code>方法获取。</p>
<h3 id="cookie" tabindex="-1"> cookie</h3>
<p>在控制器中,可以通过<code>this.ctx.cookies.get</code>方法获取 cookie。</p>
<h3 id="session" tabindex="-1"> session</h3>
<p>默认情况下,<code>Uma</code>的 Session 插件通过 cookie 存储 session,详细的配置和用法可以通过 Plugin#Session 获取。</p>
<p>在控制器中,可以通过<code>this.ctx.session</code>对象获取相应的 session 值。</p>
<h3 id="body-和上传文件的获取" tabindex="-1"> body 和上传文件的获取</h3>
<h2 id="发送响应" tabindex="-1"> 发送响应</h2>
<p>返回的数据都可以通过<code>Result</code>来返回。 <code>BaseController</code>也内置了<code>Result</code>一样的方法,还内置了一些方便使用的方法。</p>
<h3 id="set-status-status-number" tabindex="-1"> set status(status: number);</h3>
<p>正确的设置 http 的状态码,可以增强请求的语义性。可以通过<code>this.status = code</code>设置返回的状态码。</p>
<h3 id="get-useragent-any" tabindex="-1"> get userAgent(): any;</h3>
<p>获取请求的 user-agent</p>
<h3 id="get-param-any" tabindex="-1"> get param(): any;</h3>
<p>获取请求的参数</p>
<h3 id="setheader-name-string-any-value-string-string-void" tabindex="-1"> setHeader(name: string | any, value: string | string[]): void;</h3>
<p>设置请求 header</p>
<h3 id="getheader-name-string-any-any" tabindex="-1"> getHeader(name: string | any): any;</h3>
<p>获取请求 header</p>
<h3 id="统一返回-result" tabindex="-1"> 统一返回 Result</h3>
<p>在 controller 中可以 <code>return Result[...](...)</code>,也可以 <code>return this[...](...)</code>,更多介绍见<a href="/development/Result.html">Result</a>。</p>
<h4 id="this-send-val-status" tabindex="-1"> <code>this.send(val, status)</code></h4>
<p>用于快捷返回文本内容,第二个参数为返回状态码。</p>
<h4 id="this-json-data" tabindex="-1"> <code>this.json(data)</code></h4>
<p>返回 json 数据,并将<code>content-type</code>设置为<code>application/json</code>。</p>
<h4 id="this-jsonp-data-callback" tabindex="-1"> <code>this.jsonp(data, callback)</code></h4>
<p>以 jsonp 的形式返回数据。</p>
<h4 id="this-view-templatepath-data" tabindex="-1"> <code>this.view(templatePath, data)</code></h4>
<p>通过渲染模板的方式将数据返回。</p>
<h4 id="this-stream-data-filename" tabindex="-1"> <code>this.stream(data, fileName)</code></h4>
<p>将文件以流(stream)的方式返回</p>
<h4 id="this-download-filepath-opts" tabindex="-1"> <code>this.download(filePath, opts)</code></h4>
<p>下载文件</p>
<h4 id="this-done" tabindex="-1"> <code>this.done()</code></h4>
<p>使用 ctx 进行完了操作,不需要使用 Result 进行其它的返回时使用此方法,常用于框架的迁移。</p>
]]></content>
</entry>
<entry>
<title type="html">修饰器(Decorator)</title>
<id>https://umajs.github.io/development/Decorator.html</id>
<link href="https://umajs.github.io/development/Decorator.html"/>
<updated>2023-03-17T10:20:25.147Z</updated>
<content type="html"><![CDATA[<h1 id="修饰器-decorator" tabindex="-1"> 修饰器(Decorator)</h1>
<p>框架大量功能都是以 Decorator(修饰器)的方式使用。</p>
<h2 id="resource、-inject-修饰器" tabindex="-1"> @Resource、@Inject 修饰器</h2>
<p><a href="/development/IOC.html#resource%E3%80%81-inject-%E4%BF%AE%E9%A5%B0%E5%99%A8">IOC 参考文档</a></p>
<h2 id="service-修饰器" tabindex="-1"> @Service 修饰器</h2>
<p><a href="/development/IOC.html#service%E4%BF%AE%E9%A5%B0%E5%99%A8">Service 参考文档</a></p>
<h2 id="around-修饰器" tabindex="-1"> @Around 修饰器</h2>
<p><a href="/development/AOP.html#around%E4%BF%AE%E9%A5%B0%E5%99%A8">Acpect 参考文档</a></p>
<h2 id="middleware-修饰器" tabindex="-1"> Middleware 修饰器</h2>
<p><a href="/development/Middleware.html#middleware%E8%A3%85%E9%A5%B0%E5%99%A8">Middleware 参考文档</a></p>
<h2 id="path" tabindex="-1"> @Path</h2>
<p><a href="/development/Router.html#path%E4%BF%AE%E9%A5%B0%E5%99%A8">Router 参考文档</a></p>
<h2 id="参数装饰器-param-query-body" tabindex="-1"> 参数装饰器 <a href="/other/ArgDecorator.html">@Param , @Query, @Body</a></h2>
<h2 id="自定义参数装饰器-createargdecorator" tabindex="-1"> 自定义参数装饰器 createArgDecorator</h2>
<h3 id="注意" tabindex="-1"> 注意</h3>
<blockquote>
<p>从 v1.1.* 版本开始,<code>createArgDecorator</code> 更新了参数方式,使传入参数不受一个的限制。</p>
</blockquote>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// v1.0.*</span></span>
<span><span style="color: #FF7B72">function</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">createArgDecorator</span><span style="color: #C9D1D9">(</span><span style="color: #D2A8FF">fn</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> (</span><span style="color: #FFA657">argKey</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span><span style="color: #C9D1D9">, </span><span style="color: #FFA657">ctx</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">IContext</span><span style="color: #C9D1D9">) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">any</span><span style="color: #C9D1D9">)</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> (</span><span style="color: #FF7B72">...</span><span style="color: #FFA657">argProps</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">any</span><span style="color: #C9D1D9">[]) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">ParameterDecorator</span><span style="color: #C9D1D9">;</span></span>
<span></span>
<span><span style="color: #8B949E">// v1.1.*</span></span>
<span><span style="color: #FF7B72">function</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">createArgDecorator</span><span style="color: #C9D1D9">(</span><span style="color: #D2A8FF">fn</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> (</span><span style="color: #FFA657">ctx</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">IContext</span><span style="color: #C9D1D9">, </span><span style="color: #FF7B72">...</span><span style="color: #FFA657">argProps</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">any</span><span style="color: #C9D1D9">[]) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">any</span><span style="color: #C9D1D9">)</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> (</span><span style="color: #FF7B72">...</span><span style="color: #FFA657">argProps</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">any</span><span style="color: #C9D1D9">[]) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">ParameterDecorator</span><span style="color: #C9D1D9">;</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br></div></div><h3 id="示例如下" tabindex="-1"> 示例如下</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// user.controller.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Param } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { AgeCheck } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'../decorator/AgeCheck'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> User </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">save</span><span style="color: #FFA657">(@</span><span style="color: #D2A8FF">Param</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #FFA657">) name</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">string</span><span style="color: #FFA657">, @</span><span style="color: #D2A8FF">AgeCheck</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'age'</span><span style="color: #FFA657">) age</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">number</span><span style="color: #FFA657">) </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// ...</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span>
<span><span style="color: #8B949E">// decorator/AgeCheck.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { createArgDecorator, Result, IContext } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #8B949E">/**</span></span>
<span><span style="color: #8B949E"> * 1、参数的聚合 Model</span></span>
<span><span style="color: #8B949E"> * 2、参数的校验</span></span>
<span><span style="color: #8B949E"> * 3、参数的转换</span></span>
<span><span style="color: #8B949E"> * 4、便捷方法</span></span>
<span><span style="color: #8B949E"> * 5、utils、config 等也可以通过此装饰器快速引用</span></span>
<span><span style="color: #8B949E"> */</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">AgeCheck</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">createArgDecorator</span><span style="color: #C9D1D9">((</span><span style="color: #FFA657">ctx</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">IContext</span><span style="color: #C9D1D9">, </span><span style="color: #FFA657">ageKey</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span><span style="color: #C9D1D9">) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">let</span><span style="color: #C9D1D9"> age </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> ctx.query[ageKey]</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">if</span><span style="color: #C9D1D9"> (age </span><span style="color: #FF7B72">===</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">undefined</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">json</span><span style="color: #C9D1D9">({</span></span>
<span><span style="color: #C9D1D9"> code: </span><span style="color: #79C0FF">0</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> msg: </span><span style="color: #A5D6FF">'请加上 age 参数'</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> })</span></span>
<span></span>
<span><span style="color: #C9D1D9"> age </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">+</span><span style="color: #C9D1D9">age</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">if</span><span style="color: #C9D1D9"> (</span><span style="color: #79C0FF">Number</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">isNaN</span><span style="color: #C9D1D9">(age) </span><span style="color: #FF7B72">||</span><span style="color: #C9D1D9"> age </span><span style="color: #FF7B72"><</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">0</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">||</span><span style="color: #C9D1D9"> age </span><span style="color: #FF7B72">></span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">120</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">json</span><span style="color: #C9D1D9">({</span></span>
<span><span style="color: #C9D1D9"> code: </span><span style="color: #79C0FF">0</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> msg: </span><span style="color: #A5D6FF">'请传入正确的 age 参数'</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> })</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> age</span></span>
<span><span style="color: #C9D1D9">})</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br><span>14</span><br><span>15</span><br><span>16</span><br><span>17</span><br><span>18</span><br><span>19</span><br><span>20</span><br><span>21</span><br><span>22</span><br><span>23</span><br><span>24</span><br><span>25</span><br><span>26</span><br><span>27</span><br><span>28</span><br><span>29</span><br><span>30</span><br><span>31</span><br><span>32</span><br><span>33</span><br><span>34</span><br><span>35</span><br><span>36</span><br><span>37</span><br><span>38</span><br><span>39</span><br></div></div>]]></content>
</entry>
<entry>
<title type="html">依赖注入(IOC)</title>
<id>https://umajs.github.io/development/IOC.html</id>
<link href="https://umajs.github.io/development/IOC.html"/>
<updated>2023-03-17T10:20:25.147Z</updated>
<content type="html"><![CDATA[<h1 id="依赖注入-ioc" tabindex="-1"> 依赖注入(IOC)</h1>
<p>IOC(Inversion of Control)控制反转,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。</p>
<h2 id="什么是-ioc" tabindex="-1"> 什么是 IOC</h2>
<p><code>控制反转(Inversion of Control)</code>是一种借助于<code>第三方容器</code>,实现对具有依赖关系的<code>对象之间解耦</code>的一种<code>代码设计思路</code>。</p>
<p>例如我们的程序中有对象 A、B、C、D 像齿轮一样相互依赖的运作着,如下图:</p>
<p><img src="@source/../public/images/IOC-di4.png" alt="images"></p>
<p>我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整个齿轮组的正常运转。</p>
<p>为了解决对象之间的耦合度过高的问题,软件专家 Michael Mattson 提出了 IOC 理论,借助于“第三方容器”实现对象之间的解耦,如下图:</p>
<p><img src="@source/../public/images/IOC-di5.png" alt="images"></p>
<p>由于引进了中间位置的“第三方容器”,也就是<code>IOC容器</code>,使得 A、B、C、D 这 4 个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方容器”了,全部对象的控制权全部上缴给“第三方”IOC 容器。</p>
<p>当对象 A 需要用到对象 B 的时候,只需要通过 IOC 容器来获取<code>对象B的实例</code>,而不需要自己创建一个对象 B 实例。而 IOC 容器又通过<code>依赖注入</code>的方式将对象 A 需要的对象 B 实例<code>注入</code>到对象 A 中。</p>
<p><img src="@source/../public/images/IOC-di3.png" alt="images"></p>
<h2 id="resource、-inject-修饰器" tabindex="-1"> @Resource、@Inject 修饰器</h2>
<p>Uma 提供了<code>@Resource修饰器</code>和<code>@Inject修饰器</code>来实现<code>IOC容器</code>和<code>依赖注入</code></p>
<p>@Resource 修饰器可以修饰<code>${URSA_ROOT}中的任意class</code>,被@Resource 修饰的 class,将会在 IOC 容器中加入一个该<code>class的实例</code></p>
<blockquote>
<p>Resource 装饰器还可以传入参数作为 class 的实例化参数。
export declare function Resource(...props: any[]): Function;</p>
</blockquote>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Resource</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'user'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #FF7B72">class</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Test</span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">constructor</span><span style="color: #C9D1D9">(</span><span style="color: #FF7B72">readonly</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">tablename</span><span style="color: #C9D1D9">) {</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br></div></div><p>@Inject 修饰器可以将<code>被@Resource修饰过</code>的 class 的<code>实例</code>注入到指定变量中</p>
<p>例如,我们在<code>${URSA_ROOT}/model</code>中创建一个<code>user.model.ts</code>,并使用@Resource 将该类实例化后加入到资源容器中.</p>
<p><strong>注意</strong><code>inject</code>装饰器在V2版本之后只接受函数类型参数。</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { Resource } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #8B949E">// ===> @Resource修饰器</span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Resource</span><span style="color: #C9D1D9">()</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> UserModel {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">findAll</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// ...</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> []</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br></div></div><p>然后我们可以在 controller 中获取该 model 实例</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> BaseController,</span></span>
<span><span style="color: #C9D1D9"> Path,</span></span>
<span><span style="color: #C9D1D9"> Inject,</span></span>
<span><span style="color: #C9D1D9">} </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> UserModel </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'../model/user.model'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Index </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #8B949E">// ===> 获取实例,实例的名称为@Resource修饰的class所在的文件名</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Inject</span><span style="color: #FFA657">(</span><span style="color: #C9D1D9">UserModel</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> user</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> UserModel</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/getUser'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #FF7B72">async</span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">testModel</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// ===> 这里不需要创建user实例,@Resource已经将userModel实例化保存在容器中</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">userList</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">await</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.user.</span><span style="color: #D2A8FF">findAll</span><span style="color: #C9D1D9">()</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">json</span><span style="color: #C9D1D9">(userList)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br><span>14</span><br><span>15</span><br><span>16</span><br><span>17</span><br><span>18</span><br></div></div><p>@Resource 可以对<code>任何class进行修饰</code>,即任何资源都可以加入到容器中,然后通过依赖注入的方式使用。</p>
<p><code>@Resource修饰器支持传入参数</code>,传入的参数将会被作为修饰类实例化时的<code>构造参数</code>使用。</p>
<h2 id="service修饰器" tabindex="-1"> @Service修饰器</h2>
<p>除了提供的 <code>Resource</code> 和 <code>Inject</code> 装饰器,还有一个特殊的依赖注入装饰器 <code>Service</code>,<code>@Service</code> 装饰器仅提供 <code>Controller</code> 使用,为了方便使用,Service 注入中内置了 ctx,框架默认将<code>${URSA_ROOT}/service</code>下的文件实例化加入到<code>service的容器中</code>,当我们使用的时候,通过<code>@Service修饰器</code>去获取该实例。</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> DemoService </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'../service/demo.service'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Index </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Service</span><span style="color: #FFA657">(</span><span style="color: #C9D1D9">DemoService</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> demoService</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> DemoService</span></span>
<span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/demo'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">demoService</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// return this.demoService.loadAll();</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br></div></div><div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseService } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Demp </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseService</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">loadAll</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// return</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br></div></div><blockquote>
<p>@Service 和@Resource 最大的不同是,在@Service 修饰的方法中可以访问到<code>ctx</code>上下文对象,而@Resource 没有</p>
</blockquote>
<h3 id="非-controller-中使用-service-时-必须传入-ctx-进行实例化才能使用或者-service-类不继承-baseservice-使用-resource-容器修饰此-class。" tabindex="-1"> 非 Controller 中使用 @Service 时,必须传入 ctx 进行实例化才能使用或者 service 类不继承 BaseService,使用@Resource 容器修饰此 class。</h3>
<p><a href="/development/Service.html">Service 参考文档</a></p>
]]></content>
</entry>
<entry>
<title type="html">中间件(Middleware)</title>
<id>https://umajs.github.io/development/Middleware.html</id>
<link href="https://umajs.github.io/development/Middleware.html"/>
<updated>2023-03-17T10:20:25.147Z</updated>
<content type="html"><![CDATA[<h1 id="中间件-middleware" tabindex="-1"> 中间件(Middleware)</h1>
<p>Uma 基于 Koa2,兼容 middleware。在已有中间件的基础上提供两种使用形式:插件形式、AOP 形式。</p>
<h2 id="插件形式" tabindex="-1"> 插件形式</h2>
<h3 id="使用" tabindex="-1"> 使用</h3>
<p><code>Uma</code> 的插件机制很大部分是借用了 <code>Koa</code> 的中间件,通过插件来使用中间件更易于开发和维护,请尽量用插件形式来使用中间件,插件开发和使用请参阅
<a href="/development/Plugin.html#%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91">Plugin 参考文档</a></p>
<h3 id="其它" tabindex="-1"> 其它</h3>
<p>为了方便插件使用已发布的中间件,插件配置(plugin.config.ts)可以配置中间件便捷使用,配置如下</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// types</span></span>
<span><span style="color: #C9D1D9">[middlewareName: string]: {</span></span>
<span><span style="color: #C9D1D9"> type: </span><span style="color: #A5D6FF">'middleware'</span><span style="color: #C9D1D9">, </span><span style="color: #8B949E">// 仅在使用中间件的时候配置 type</span></span>
<span><span style="color: #C9D1D9"> handler: Koa.Middleware,</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br></div></div><div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// plugin.config.ts</span></span>
<span><span style="color: #8B949E">// 基于 koa-views 配置模板中间件</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">*</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">as</span><span style="color: #C9D1D9"> views </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'koa-views'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #C9D1D9">view: {</span></span>
<span><span style="color: #C9D1D9"> type: </span><span style="color: #A5D6FF">'middleware'</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> handler: </span><span style="color: #D2A8FF">views</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'./views'</span><span style="color: #C9D1D9">, {</span></span>
<span><span style="color: #C9D1D9"> map: { html: </span><span style="color: #A5D6FF">'nunjucks'</span><span style="color: #C9D1D9"> },</span></span>
<span><span style="color: #C9D1D9"> }),</span></span>
<span><span style="color: #C9D1D9"> }</span><span style="color: #FFA657">,</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br></div></div><blockquote>
<p>请不要在插件配置( plugin.config.ts )中进行中间件的开发,让插件的配置更加纯粹。如需要请使用插件开发。<a href="/development/Plugin.html#%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91">Plugin 参考文档</a></p>
<p>如果要动态的加载中间件,请使用复合插件形式。<a href="/development/Plugin.html#%E5%A4%8D%E5%90%88%E6%8F%92%E4%BB%B6%E5%BD%A2%E5%BC%8F">Plugin 参考文档</a></p>
</blockquote>
<h2 id="middleware装饰器" tabindex="-1"> Middleware装饰器</h2>
<blockquote>
<p>Middleware装饰器(v2+)目前只支持函数装饰,可将koa中间件作用于特定的controller函数。这可以更灵活的控制避免全局中间件的影响;将中间件局部应用于单一或者多个路由。</p>
</blockquote>
<div><pre style="background-color: #0d1117"><code><span></span>
<span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">middleware</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">async</span><span style="color: #C9D1D9"> (</span><span style="color: #FFA657">ctx</span><span style="color: #C9D1D9">,</span><span style="color: #FFA657">next</span><span style="color: #C9D1D9">)</span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">log</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">"****** middleware before ******"</span><span style="color: #C9D1D9">);</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">await</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">next</span><span style="color: #C9D1D9">();</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">log</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">"****** middleware after *******"</span><span style="color: #C9D1D9">);</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Index </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Middleware</span><span style="color: #FFA657">(</span><span style="color: #C9D1D9">middleware</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">view</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'index.html'</span><span style="color: #C9D1D9">, {</span></span>
<span><span style="color: #C9D1D9"> frameName: </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.testService.</span><span style="color: #D2A8FF">returnFrameName</span><span style="color: #C9D1D9">(),</span></span>
<span><span style="color: #C9D1D9"> });</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br><span>14</span><br><span>15</span><br></div></div><h2 id="aop-装饰器形式" tabindex="-1"> AOP 装饰器形式</h2>
<p>中间件和 Around 方式很相似,都是包裹异步方法。中间件是 next,around 是 proceed,但是他们有一些区别:</p>
<blockquote>
<p>1、中间件不能处理参数,不能处理返回结果</p>
<p>2、切面可以对参数进行修改、判断、注入等操作,还可以对返回结果进行修改、校验、统一封装等操作</p>
</blockquote>
<p>对于在中间件需要对参数,返回结构进行统一处理和校验,推荐使用 AOP 形式代码结构更清晰,可读性更强。<a href="/development/AOP.html">AOP 参考文档</a></p>
]]></content>
</entry>
<entry>
<title type="html">插件(Plugin)</title>
<id>https://umajs.github.io/development/Plugin.html</id>
<link href="https://umajs.github.io/development/Plugin.html"/>
<updated>2023-03-17T10:20:25.147Z</updated>
<content type="html"><![CDATA[<h1 id="插件-plugin" tabindex="-1"> 插件(Plugin)</h1>
<h2 id="为什么使用插件" tabindex="-1"> 为什么使用插件</h2>
<p><code>Uma</code> 的插件内部机制就是借用了 <code>Koa</code> 的中间件,但是仅有中间件无法满足框架的扩展,另外中间件的配置对于业务多样性解决也偏单一。</p>
<p><code>Uma</code> 使用插件进行框架层面拓展,不仅可以使用中间件模式进行扩展,还可以采用复合模式对 context、request、response 进行扩展,还可以对中间件的使用场景进行快速开发,例如 results(返回值)、use(无设定场景)、filter(对符合条件的路由加载中间件)、ignore(对符合条件之外的路由加载中间件)、method(对 MethodType 符合的请求加载中间件)</p>
<h2 id="插件使用" tabindex="-1"> 插件使用</h2>
<h3 id="插件安装" tabindex="-1"> 插件安装</h3>
<p>插件可以通过 npm 方式进行安装。<code>Uma</code>官方提供的插件一般使用<code>@umajs/plugin-</code>作为前缀,方便我们去搜索。同时<code>Uma</code>也可以加载应用目录内的用户自定义插件<code>plugins</code>目录。框架在读取配置后,插件的加载优先级如下:</p>
<ol>
<li>{URSA_ROOT}/plugins/{packageName}</li>
<li>{URSA_ROOT}/node_modules/{packageName}</li>
</ol>
<h3 id="插件配置" tabindex="-1"> 插件配置</h3>
<p>插件一般有默认配置,我们也可以通过自定义配置来覆盖原有配置。</p>
<p>插件的配置在 config 目录下的<code>plugin.config.ts</code>文件中,插件顺序按照 <code>config/plugin.config.ts</code> 配置的顺序进行加载。</p>
<blockquote>
<p>注意:插件的顺序会影响到插件调用其它插件的功能。</p>
</blockquote>
<h4 id="插件配置说明" tabindex="-1"> 插件配置说明</h4>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">export</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">type</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">TPluginConfig</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">enable</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">boolean</span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 是否开启插件,默认值false</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">name</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 插件名,可选</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">packageName</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// npm包名,可选,如不填写时,默认值为`@umajs/plugin-$</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">options</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">object</span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 框架会将此配置用参数形式传给插件</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br></div></div><blockquote>
<p>当 [pluginName].config.ts 存在时, 会和配置混合后传给插件</p>
</blockquote>
<h4 id="插件配置实例" tabindex="-1"> 插件配置实例</h4>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// config/plugin.config.ts</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #A5D6FF">'error-handler'</span><span style="color: #C9D1D9">: {</span></span>
<span><span style="color: #C9D1D9"> enable: </span><span style="color: #79C0FF">true</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> name: </span><span style="color: #A5D6FF">'error-handler'</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> packageName: </span><span style="color: #A5D6FF">'@umajs/plugin-error-handler'</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> options: {</span></span>
<span><span style="color: #C9D1D9"> foo: </span><span style="color: #A5D6FF">'1'</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> }, </span><span style="color: #8B949E">// 插件的实际配置</span></span>
<span><span style="color: #C9D1D9"> }</span><span style="color: #FFA657">,</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br></div></div><p>如果只需开启插件或关闭插件,可以简化配置写法:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// config/plugin.config.ts</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #A5D6FF">'error-handler'</span><span style="color: #C9D1D9">: </span><span style="color: #79C0FF">true</span><span style="color: #FFA657">,</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br></div></div><p>插件实际上是一个接收uma对象和option参数的函数,函数必须返回中间件函数或复合插件格式<a href="/plugin/dev.html#%E5%A4%8D%E5%90%88%E6%8F%92%E4%BB%B6%E5%BD%A2%E5%BC%8F">对象</a></p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// plugin/error-handler/index.ts</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> (uma</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> Uma, options</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> TView </span><span style="color: #FF7B72">=</span><span style="color: #FFA657"> {})</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> Koa.Middleware </span><span style="color: #FF7B72">=></span><span style="color: #FFA657"> </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// uma 实例化对象;options 插件配置的 options,等同于 uma.plugin['error-handler'].options</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">async</span><span style="color: #C9D1D9">(</span><span style="color: #FFA657">ctx</span><span style="color: #C9D1D9">,</span><span style="color: #FFA657">next</span><span style="color: #C9D1D9">)</span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">try</span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">await</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">next</span><span style="color: #C9D1D9">();</span></span>
<span><span style="color: #C9D1D9"> }</span><span style="color: #FF7B72">catch</span><span style="color: #C9D1D9">(e){</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">error</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'error-handler插件捕获异常'</span><span style="color: #C9D1D9">,e);</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #C9D1D9"> };</span></span>
<span><span style="color: #C9D1D9">};</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br></div></div><h2 id="插件开发" tabindex="-1"> <a href="/plugin/dev.html">插件开发</a></h2>
]]></content>
</entry>
<entry>
<title type="html">统一返回(Result)</title>
<id>https://umajs.github.io/development/Result.html</id>
<link href="https://umajs.github.io/development/Result.html"/>
<updated>2023-03-17T10:20:25.148Z</updated>
<content type="html"><![CDATA[<h1 id="统一返回-result" tabindex="-1"> 统一返回(Result)</h1>
<p>在 koa 和大多数框架中,没有统一返回,这样在使用框架返回数据的时候需要额外处理,如果要对返回结果做处理可能需要修改很多地方,但是在进行了统一返回之后这些都变得很简单。</p>
<h2 id="result" tabindex="-1"> Result</h2>
<h4 id="result-send-val-status" tabindex="-1"> <code>Result.send(val, status)</code></h4>
<p>用于快捷返回文本内容,第二个参数为返回状态码。</p>
<h4 id="result-json-data" tabindex="-1"> <code>Result.json(data)</code></h4>
<p>返回 json 数据,并将<code>content-type</code>设置为<code>application/json</code>。</p>
<h4 id="result-jsonp-data-callback" tabindex="-1"> <code>Result.jsonp(data, callback)</code></h4>
<p>以 jsonp 的形式返回数据。</p>
<h4 id="result-view-templatepath-data" tabindex="-1"> <code>Result.view(templatePath, data)</code></h4>
<p>通过渲染模板的方式将数据返回。</p>
<h4 id="result-stream-data-filename" tabindex="-1"> <code>Result.stream(data, fileName)</code></h4>
<p>将文件以流(stream)的方式返回</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/stream'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">donwStream</span><span style="color: #C9D1D9">() {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">rs</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> fs.</span><span style="color: #D2A8FF">createReadStream</span><span style="color: #C9D1D9">(path.</span><span style="color: #D2A8FF">resolve</span><span style="color: #C9D1D9">(__dirname, </span><span style="color: #A5D6FF">'./template.controller.ts'</span><span style="color: #C9D1D9">));</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">stream</span><span style="color: #C9D1D9">(rs, </span><span style="color: #A5D6FF">'controller.ts'</span><span style="color: #C9D1D9">);</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br></div></div><h4 id="result-download-filepath-opts" tabindex="-1"> <code>Result.download(filePath, opts)</code></h4>
<p>下载文件</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/download'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">downFile</span><span style="color: #C9D1D9">() {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">download</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/src/controller/template.controller.ts'</span><span style="color: #C9D1D9">);</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br></div></div><h4 id="result-done" tabindex="-1"> <code>Result.done()</code></h4>
<p>使用 ctx 进行完了操作,不需要使用 Result 进行其它的返回时使用此方法,常用于框架的迁移。</p>
<blockquote>
<p>例如下面两个方法 <code>json1</code> 和 <code>json2</code> 表示的意思是一样的。</p>
</blockquote>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">json1</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.ctx.body </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'Hello'</span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// ctx 响应</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">done</span><span style="color: #C9D1D9">()</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">json2</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'Hello'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br></div></div><h2 id="实例" tabindex="-1"> 实例</h2>
<h3 id="controller-实例" tabindex="-1"> controller 实例</h3>
<p>Uma 在需要的模板返回的数据中加入 version,这里我们用 Around 可以很容易做到。</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// version.aspect.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { IJoinPoint, IProceedJoinPoint, Result } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span><span style="color: #C9D1D9">;</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">version</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">async</span><span style="color: #C9D1D9">(</span><span style="color: #FFA657">proceedPoint</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">IProceedJoinPoint</span><span style="color: #C9D1D9"><</span><span style="color: #79C0FF">any</span><span style="color: #C9D1D9">>) {</span></span>
<span><span style="color: #C9D1D9"> const result: Result </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">await</span><span style="color: #C9D1D9"> proceedPoint.</span><span style="color: #D2A8FF">proceed</span><span style="color: #C9D1D9">();</span></span>
<span></span>
<span><span style="color: #C9D1D9"> result.data.version </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'v1.0.0'</span><span style="color: #C9D1D9">;</span></span>
<span></span>
<span><span style="color: #C9D1D9"> return result;</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span>
<span><span style="color: #8B949E">// info.controller.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Aournd, Result } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span><span style="color: #C9D1D9">;</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { version } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'./aspect/version.aspect'</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Info </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Aournd</span><span style="color: #FFA657">(</span><span style="color: #C9D1D9">version</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">info</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">view</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'info.html'</span><span style="color: #C9D1D9">, {});</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br><span>14</span><br><span>15</span><br><span>16</span><br><span>17</span><br><span>18</span><br><span>19</span><br><span>20</span><br><span>21</span><br></div></div><h3 id="controller-参数实例" tabindex="-1"> controller 参数实例</h3>
<p><a href="/development/Decorator.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8F%82%E6%95%B0%E8%A3%85%E9%A5%B0%E5%99%A8-createargdecorator">createArgDecorator 参考文档</a></p>
<h2 id="扩展" tabindex="-1"> 扩展</h2>
<p>想要扩展 <code>Result</code> 的返回方法,请使用 <code>plugin</code> 的扩展方式,示例如下:</p>
<blockquote>
<p>扩展带状态的 redirect 方法</p>
</blockquote>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// plugin.config.ts</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #C9D1D9">redirect: </span><span style="color: #79C0FF">true</span><span style="color: #FFA657">,</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br></div></div><div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// plugins/redirect/index.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { IContext, TPlugin, RequestMethod, Result </span><span style="color: #FF7B72">as</span><span style="color: #C9D1D9"> R } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #FF7B72">type</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">TRedirect2</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">url</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">status</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">number</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">class</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Result</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">extends</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">R</span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">static</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">redirect2</span><span style="color: #C9D1D9">(</span><span style="color: #FFA657">url</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span><span style="color: #C9D1D9">, </span><span style="color: #FFA657">status</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">number</span><span style="color: #C9D1D9">) {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">new</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">Result</span><span style="color: #C9D1D9">({</span></span>
<span><span style="color: #C9D1D9"> type: </span><span style="color: #A5D6FF">'redirect2'</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> data: {</span></span>
<span><span style="color: #C9D1D9"> url,</span></span>
<span><span style="color: #C9D1D9"> status,</span></span>
<span><span style="color: #C9D1D9"> },</span></span>
<span><span style="color: #C9D1D9"> })</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> ()</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> TPlugin </span><span style="color: #FF7B72">=></span><span style="color: #FFA657"> </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> results: {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">redirect2</span><span style="color: #C9D1D9">(</span><span style="color: #FFA657">ctx</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">IContext</span><span style="color: #C9D1D9">, </span><span style="color: #FFA657">data</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">TRedirect2</span><span style="color: #C9D1D9">) {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> { </span><span style="color: #79C0FF">url</span><span style="color: #C9D1D9">, </span><span style="color: #79C0FF">status</span><span style="color: #C9D1D9"> } </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> data</span></span>
<span></span>
<span><span style="color: #C9D1D9"> ctx.status </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> status</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> ctx.</span><span style="color: #D2A8FF">redirect</span><span style="color: #C9D1D9">(url)</span></span>
<span><span style="color: #C9D1D9"> },</span></span>
<span><span style="color: #C9D1D9"> },</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br><span>14</span><br><span>15</span><br><span>16</span><br><span>17</span><br><span>18</span><br><span>19</span><br><span>20</span><br><span>21</span><br><span>22</span><br><span>23</span><br><span>24</span><br><span>25</span><br><span>26</span><br><span>27</span><br><span>28</span><br><span>29</span><br><span>30</span><br><span>31</span><br><span>32</span><br><span>33</span><br></div></div><div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// index.controller.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { Result } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'../plugins/test/index'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Index </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/r'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">extendResult</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> Result.</span><span style="color: #D2A8FF">redirect2</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/'</span><span style="color: #C9D1D9">, </span><span style="color: #79C0FF">301</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br></div></div>]]></content>
</entry>
<entry>
<title type="html">路由(Router)</title>
<id>https://umajs.github.io/development/Router.html</id>
<link href="https://umajs.github.io/development/Router.html"/>
<updated>2023-03-17T10:20:25.148Z</updated>
<content type="html"><![CDATA[<h1 id="路由-router" tabindex="-1"> 路由(Router)</h1>
<p>路由主要用于确认如何响应客户端的请求,当用户访问一个地址时,需要找到指定的 controller 的指定方法对用户请求进行处理。确认一个请求主要对请求的两部分:路径和特定 HTTP 请求方法,进行判断。</p>
<h2 id="使用" tabindex="-1"> 使用</h2>
<p>为了方便用户对路由的选择,Router 被作为参数的方式传入到 Uma 中。</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { Router } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/router'</span></span>
<span></span>
<span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">uma</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> Uma.</span><span style="color: #D2A8FF">instance</span><span style="color: #C9D1D9">({</span></span>
<span><span style="color: #C9D1D9"> Router,</span></span>
<span><span style="color: #C9D1D9"> ROOT: __dirname,</span></span>
<span><span style="color: #C9D1D9">})</span></span>
<span></span>
<span><span style="color: #C9D1D9">uma.</span><span style="color: #D2A8FF">start</span><span style="color: #C9D1D9">(</span><span style="color: #79C0FF">8058</span><span style="color: #C9D1D9">)</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br></div></div><h2 id="path-修饰器" tabindex="-1"> @Path 修饰器</h2>
<p>如果你不想通过默认路由的方式访问时,<code>Uma</code>提供了<code>@Path修饰器</code>来指定 controller 方法被访问的 URI 格式。</p>
<blockquote>
<p>可以装饰 class,作为跟路由,只装饰 class 不生效,必须和 method 装饰配合使用。装饰 class 只有能有一个 string 参数
可以装饰 method,没有根路由的时候直接作为路由使用,有根路由的时候和根路由组合使用</p>
<p>export declare function Path(...args: [...string[]] | [TPathObjArgs]): Function;</p>
<p>args 路由参数 eg:</p>
<p>Path() // 仅在 class 有路由装饰时 装饰 method 使用</p>
<p>Path('/p1')</p>
<p>Path('/p1', 'p2')</p>
<p>Path({ value: '/p1' })</p>
<p>Path({ value: '/p1', method: RequestMethod.GET })</p>
<p>Path({ value: ['/p1', '/p2'], method: RequestMethod.GET })</p>
<p>Path({ value: ['/p1', '/p2'], method: [RequestMethod.GET, RequestMethod.POST] })</p>
</blockquote>
<h3 id="修饰-class" tabindex="-1"> 修饰 class</h3>
<p>@Path 修饰器除了能修饰方法外,还可以修饰 controller 的 class,被修饰后的 class,如果内层的方法同时也添加了 @Path 修饰器,那么该方法的访问路径将和 class 上的 @Path 指定路径合并使用。</p>
<p>例如我们对上面创建的 test.controller.ts 文件做以下修改:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/page'</span><span style="color: #C9D1D9">) </span><span style="color: #8B949E">// 根路由</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">() </span><span style="color: #8B949E">// 路由: /page</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/home'</span><span style="color: #FFA657">) </span><span style="color: #8B949E">// 路由: /page/home</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is page/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">test</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br></div></div><p>在浏览器地址栏通过访问<code>127.0.0.1:端口号/page/home</code> 或 <code>127.0.0.1:端口号/page/</code>就可以看到页面显示出<code>this is page/index router</code>。</p>
<blockquote>
<p>注意:v2.0 版本之后,框架取消了文件默认路由,即我们不能通过<code>127.0.0.1:端口号/page/test</code>访问到目标函数,接口将会返回 Not Found。请确保所有路由都被<code>@Path</code>装饰。</p>
<p>同时,访问<code>127.0.0.1:端口号/page</code>也可以看到页面显示出<code>this is test/index router</code></p>
</blockquote>
<h3 id="修饰方法" tabindex="-1"> 修饰方法</h3>
<p>例如我们对上面创建的 test.controller.ts 文件做以下修改:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/home'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br></div></div><p>在浏览器地址栏通过访问<code>127.0.0.1:端口号/home</code>就可以看到页面显示出<code>this is test/index router</code>。</p>
<blockquote>
<p>注意:此时,在浏览器地址栏访问<code>127.0.0.1:端口号/test/index</code>就不能访问到 index 方法了,因为在<code>Uma</code>中,被@Path 修饰器修饰过的方法,不能再通过默认路由的方式访问。</p>
</blockquote>
<h3 id="methodtype" tabindex="-1"> MethodType</h3>
<p>在很多访问中,我们需要加入 MethodType 的限制,示例如下:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path, RequestMethod } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">({ </span><span style="color: #C9D1D9">value: </span><span style="color: #A5D6FF">'/home'</span><span style="color: #FFA657">, </span><span style="color: #C9D1D9">method: RequestMethod.</span><span style="color: #79C0FF">POST</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">})</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br></div></div><p>在浏览器地址栏通过访问<code>127.0.0.1:端口号/home</code>会展示 NOT FOUND,这是因为限制了只能采用 POST 访问。</p>
<blockquote>
<p>注意:框架内置了 POST 请求处理 <code>koa-body</code>,如果需要开启,实例化 <code>Uma</code> 时需要传入 <code>bodyParse</code> 参数,并且安装 <code>koa-body</code> 依赖</p>
</blockquote>
<h3 id="指定多个路径" tabindex="-1"> 指定多个路径</h3>
<p>同一个方法上允许设置多个 Path 路径。</p>
<p>例如我们对上面创建的 test.controller.ts 文件做以下修改:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/page'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/home'</span><span style="color: #FFA657">, </span><span style="color: #A5D6FF">'/abc'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br></div></div><p>在浏览器地址栏通过访问<code>127.0.0.1:端口号/page/home</code>或者<code>127.0.0.1:端口号/page/abc</code>都可以看到页面显示出<code>this is test/index router</code>。</p>
<p>也可以通过多个@Path 修饰器修饰的方式指定多个路径。</p>
<p>例如我们对上面创建的 test.controller.ts 文件做以下修改:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/page'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/home'</span><span style="color: #FFA657">, </span><span style="color: #A5D6FF">'/abc'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/test'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br></div></div><p>在浏览器地址栏通过访问<code>127.0.0.1:端口号/page/home</code>或者<code>127.0.0.1:端口号/page/abc</code>或者<code>127.0.0.1:端口号/page/test</code>都可以看到页面显示出<code>this is test/index router</code>。</p>
<p>和方法不同,一个 class 只允许使用一个@Path 修饰器,同时一个@Path 修饰器只接收一个参数。</p>
<p>例如我们对上面创建的 test.controller.ts 文件做以下修改:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/page'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/tpl'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/home'</span><span style="color: #FFA657">, </span><span style="color: #A5D6FF">'/abc'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/test'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br></div></div><p>此时,只有最上面的<code>@Path('/page')</code>生效了,因为修饰器会先执行最接近自己的,@Path('/tpl')先被作用,但是@Path('/page')又将它覆盖了。</p>
<p>同样,如果你在 class 上设置<code>@Path('/page', '/tpl')</code>这种传入多个参数的格式,程序会报错,因为修饰 class 时,@Path 只接收一个参数。</p>
<h3 id="正则匹配" tabindex="-1"> 正则匹配</h3>
<p>我们对上面这种直接使用具体字符串形式设置的路由称为<code>静态路由</code>,路径除了使用<code>/home</code>这种字符串的格式外,还支持使用正则形式,我们称之为<code>正则路由</code>。</p>
<p>例如我们对上面创建的 test.controller.ts 文件做以下修改:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/page'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/:name'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br></div></div><p>在浏览器地址栏通过访问<code>127.0.0.1:端口号/page/任意字符</code>都可以看到页面显示出<code>this is test/index router</code>。同时,我们可以通过<code>@Param修饰器</code>或者<code>ctx.params</code>的方式获取到当前<code>name</code>的值,@Param 修饰器会在后面介绍。</p>
<p>正则路由通过<a href="https://github.com/pillarjs/path-to-regexp" target="_blank" rel="noopener noreferrer">path-to-regexp</a>库进行匹配,具体格式格式参考 path-to-regexp 库。</p>
<h3 id="匹配顺序" tabindex="-1"> 匹配顺序</h3>
<p><code>Uma</code>会按照的指定顺序去匹配路由,当命中某一规则时,即进入该 controller 的方法中,了解匹配的顺序当我们设置了重复的路由时很有帮助。</p>
<p><code>Uma</code>匹配路由的顺序如下:</p>
<p><img src="@source/../public/images/Router-rule.png" alt="images"></p>
<p>请求进来时,会先从静态路由中查找是否有匹配到的,没有的话会从正则路由中匹配是否有满足的,还未找到的话会按照静态路由的格式查找是否有匹配的,当这几种情况都不满足时,返回 Not Found。</p>
<h3 id="path-扩展" tabindex="-1"> Path 扩展</h3>
<p>框架在 <code>@Path</code> 装饰器的基础上还提供了一些其它快捷的路由装饰器 <a href="/other/path.html">@umajs/path</a></p>
<h2 id="路由参数处理" tabindex="-1"> 路由参数处理</h2>
<p>在上面的正则路由中我们提到过@Param 修饰器,<code>UMajs</code>中默认只提供了两种修饰器@Param 和@Query 来方便的获取请求中的参数。对于更丰富的参数处理场景,框架提供了一个专门处理参数的装饰器工具包,<a href="/other/ArgDecorator.html">@umajs/arg-decorator</a>;方便开发者对参数进行接收,校验判断和类型转换。</p>
<h3 id="param-query-参数处理" tabindex="-1"> @Param,@Query 参数处理</h3>
<p>例如我们对上面创建的 test.controller.ts 文件做以下修改:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { Param, Query } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/arg-decorator'</span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/page'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/:name'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">(@</span><span style="color: #D2A8FF">Param</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #FFA657">) name</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">string</span><span style="color: #FFA657">, @</span><span style="color: #D2A8FF">Query</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #FFA657">) title</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">string</span><span style="color: #FFA657">) </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">log</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">`name: ${</span><span style="color: #C9D1D9">name</span><span style="color: #A5D6FF">}`</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">log</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">`title: ${</span><span style="color: #C9D1D9">title</span><span style="color: #A5D6FF">}`</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br></div></div><p>在浏览器中访问<code>127.0.0.1:端口号/page/test?name=uma</code>,我们可以看到控制台打印出:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9">name: </span><span style="color: #79C0FF">test</span></span>
<span><span style="color: #C9D1D9">title: uma</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br></div></div><p>@Param 和@Query 修饰器可以快捷的获取到请求中的 param 和 query 参数,@Param 传入的名称要和@Path 中设置的名称一致,@Query 传入的名称要和请求的 query 参数名称一致,才能正确获取到。</p>
<p>同时,使用@Param 和@Query 修饰器不区分参数顺序</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">-</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">index</span><span style="color: #C9D1D9">(@</span><span style="color: #D2A8FF">Param</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #C9D1D9">) name: string, @</span><span style="color: #D2A8FF">Query</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #C9D1D9">) title: string)</span></span>
<span><span style="color: #8B949E">// 参数顺序变化也可以正确获取</span></span>
<span><span style="color: #FF7B72">+</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">index</span><span style="color: #C9D1D9">(@</span><span style="color: #D2A8FF">Query</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #C9D1D9">) title: string, @</span><span style="color: #D2A8FF">Param</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #C9D1D9">) name: string)</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br></div></div><p>当然,除了通过@Param 和@Query 修饰器的方式获取参数外,<code>Uma</code>还保留了 koa 的参数获取方式,可以从上下文中获取:</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseController, Path } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { Param, Query } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/arg-decorator'</span></span>
<span></span>
<span><span style="color: #C9D1D9">@</span><span style="color: #D2A8FF">Path</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'/page'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Test </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/:name'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">index</span><span style="color: #FFA657">(@</span><span style="color: #D2A8FF">Param</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #FFA657">) name</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">string</span><span style="color: #FFA657">, @</span><span style="color: #D2A8FF">Query</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'name'</span><span style="color: #FFA657">) title</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">string</span><span style="color: #FFA657">) </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// ====> 从ctx中获取参数</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">log</span><span style="color: #C9D1D9">(</span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.ctx.param.name)</span></span>
<span><span style="color: #C9D1D9"> console.</span><span style="color: #D2A8FF">log</span><span style="color: #C9D1D9">(</span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.ctx.query.title)</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">.</span><span style="color: #D2A8FF">send</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'this is test/index router'</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br></div></div><p><strong>对于POST类型路由请求,参数获取和处理请查看<a href="/other/ArgDecorator.html#%E7%A4%BA%E4%BE%8B">@Body</a></strong></p>
]]></content>
</entry>
<entry>
<title type="html">服务(Service)</title>
<id>https://umajs.github.io/development/Service.html</id>
<link href="https://umajs.github.io/development/Service.html"/>
<updated>2023-03-17T10:20:25.148Z</updated>
<content type="html"><![CDATA[<h1 id="服务-service" tabindex="-1"> 服务(Service)</h1>
<h2 id="使用" tabindex="-1"> 使用</h2>
<h3 id="cli-工具在初始化会自动生成-service-目录-可直接在-service-目录中编写-service" tabindex="-1"> cli 工具在初始化会自动生成 service 目录,可直接在 service 目录中编写 service</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #c9d1d9">app
|- src
|-middleware
|-config
|-controller
|-service
|-demo.service.ts
</span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br></div></div><h3 id="命名规范-service-ts" tabindex="-1"> 命名规范: <code>*.service.ts</code></h3>
<h3 id="编写-service-时需继承默认-baseservice-以便我们将-service-挂载到-ctx-中" tabindex="-1"> 编写 service 时需继承默认 baseService 以便我们将 service 挂载到 ctx 中</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseService } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> demo </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseService</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">demoService</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'this is demo service'</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br></div></div><h3 id="controller-中使用" tabindex="-1"> controller 中使用</h3>
<ul>
<li>引入 service</li>
<li>依赖注入 <code>@Service(serviceClazz)</code> , <em>注意</em>:在V2之后,Service参数装饰器只接受class类型参数。不再支持传入文件名字符串。</li>
<li>注入之后可直接使用无需再进行实例</li>
</ul>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// controller</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> DemoService </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'../service/demo.service'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Index </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseController</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Service</span><span style="color: #FFA657">(</span><span style="color: #C9D1D9">DemoService</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> demoService</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> DemoService</span></span>
<span></span>
<span><span style="color: #FFA657"> @</span><span style="color: #D2A8FF">Path</span><span style="color: #FFA657">(</span><span style="color: #A5D6FF">'/demo'</span><span style="color: #FFA657">)</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">demoService</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// return this.demoService.loadAll();</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br></div></div><div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// service</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { BaseService } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">class</span><span style="color: #FFA657"> Demp </span><span style="color: #FF7B72">extends</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">BaseService</span><span style="color: #FFA657"> {</span></span>
<span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">loadAll</span><span style="color: #FFA657">() </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// return</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #FFA657">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br></div></div><h3 id="在非-controller-中使用-service-时-必须传入-ctx-进行实例化才能使用。" tabindex="-1"> 在非 Controller 中使用 Service 时,必须传入 ctx 进行实例化才能使用。</h3>
<blockquote>
<p>如果<code>Service</code>不需要传入<code>ctx</code> ,则无需继承<code>BaseService</code></p>
</blockquote>
<ul>
<li>在插件中使用</li>
</ul>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// plugin</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> DemoService </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'../service/demo.service'</span><span style="color: #C9D1D9">;</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> (uma</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> Uma, options</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> </span><span style="color: #79C0FF">any</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">=</span><span style="color: #FFA657"> {})</span><span style="color: #FF7B72">:</span><span style="color: #FFA657"> Koa.Middleware </span><span style="color: #FF7B72">=></span><span style="color: #FFA657"> </span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> (ctx, next) </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">></span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> const demoService: DemoService </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">new</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">DemoService</span><span style="color: #C9D1D9">(ctx);</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// ...</span></span>
<span><span style="color: #C9D1D9"> };</span></span>
<span><span style="color: #C9D1D9">};</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br></div></div><ul>
<li>在 Around 面向切面编程时使用</li>
</ul>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// src/aspect/demo.aspect.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> DemoService </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'../service/demo.service'</span></span>
<span></span>
<span><span style="color: #FF7B72">export</span><span style="color: #FFA657"> </span><span style="color: #FF7B72">default</span><span style="color: #FFA657"> </span><span style="color: #C9D1D9">async</span><span style="color: #FFA657"> </span><span style="color: #D2A8FF">around</span><span style="color: #FFA657">(</span><span style="color: #C9D1D9">proceedPoint</span><span style="color: #FFA657">: </span><span style="color: #C9D1D9">IProceedJoinPoint</span><span style="color: #FFA657">) {</span></span>
<span><span style="color: #FFA657"> const { </span><span style="color: #C9D1D9">target</span><span style="color: #FFA657">, </span><span style="color: #C9D1D9">proceed</span><span style="color: #FFA657">, </span><span style="color: #C9D1D9">args </span><span style="color: #FFA657">} </span><span style="color: #FF7B72">=</span><span style="color: #FFA657"> </span><span style="color: #C9D1D9">proceedPoint</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">demoService</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">DemoService</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">new</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">DemoService</span><span style="color: #C9D1D9">(target.ctx)</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">result</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">await</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">proceed</span><span style="color: #C9D1D9">(</span><span style="color: #FF7B72">...</span><span style="color: #C9D1D9">args)</span></span>
<span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">return</span><span style="color: #C9D1D9"> result</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br></div></div><p><strong>此外,框架还提供了@Resource 和@Inject 装饰器来实现<code>IOC容器</code>和<code>依赖注入</code></strong></p>
<p><a href="/development/IOC.html">IOC 参考文档</a></p>
]]></content>
</entry>
<entry>
<title type="html">Uma 对象</title>
<id>https://umajs.github.io/development/Uma.html</id>
<link href="https://umajs.github.io/development/Uma.html"/>
<updated>2023-03-17T10:20:25.149Z</updated>
<content type="html"><![CDATA[<h1 id="uma-对象" tabindex="-1"> Uma 对象</h1>
<p>框架向外暴露了 Uma 对象,方便在项目中随时调用</p>
<h2 id="api" tabindex="-1"> API</h2>
<h3 id="uma-env" tabindex="-1"> uma.env</h3>
<p>当前运行环境,可以在入口文件中定义</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// app.ts</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> Uma </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/core'</span></span>
<span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9"> { Router } </span><span style="color: #FF7B72">from</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'@umajs/router'</span></span>
<span></span>
<span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">uma</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> Uma.</span><span style="color: #D2A8FF">instance</span><span style="color: #C9D1D9">({</span></span>
<span><span style="color: #C9D1D9"> Router,</span></span>
<span><span style="color: #C9D1D9"> ROOT: __dirname,</span></span>
<span><span style="color: #C9D1D9"> env: process.argv.</span><span style="color: #D2A8FF">indexOf</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'production'</span><span style="color: #C9D1D9">) </span><span style="color: #FF7B72">></span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">-</span><span style="color: #79C0FF">1</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">?</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'production'</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'development'</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9">})</span></span>
<span></span>
<span><span style="color: #C9D1D9">uma.</span><span style="color: #D2A8FF">start</span><span style="color: #C9D1D9">(</span><span style="color: #79C0FF">8058</span><span style="color: #C9D1D9">)</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br></div></div><h3 id="uma-config" tabindex="-1"> uma.config</h3>
<p>当前项目正在使用的配置信息,对 <code>config</code> 目录下的配置进行处理后得到</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9">{</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">"plugin"</span><span style="color: #C9D1D9">: {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">"logger"</span><span style="color: #C9D1D9">: </span><span style="color: #79C0FF">true</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">"model"</span><span style="color: #C9D1D9">: </span><span style="color: #79C0FF">true</span></span>
<span><span style="color: #C9D1D9"> },</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">"status"</span><span style="color: #C9D1D9">: {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">"_404"</span><span style="color: #C9D1D9">: </span><span style="color: #A5D6FF">"[object, function]"</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br></div></div><h3 id="uma-options" tabindex="-1"> uma.options</h3>
<p>初始化<code>Uma</code>时传入的参数,参数包括</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">type</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">TUmaOption</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 路由</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">Router</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Function</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 代码根路径,用于加载代码</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">ROOT</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 运行环境</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">env</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'development'</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">|</span><span style="color: #C9D1D9"> </span><span style="color: #A5D6FF">'production'</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">|</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 配置文件夹路径</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">configPath</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">string</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 需要拿到真实用户ip时设置为true</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">proxy</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">boolean</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">subdomainOffset</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">number</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">jsonpBody</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">TJsonpBody</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 自带 koa-body 时的配置,不配置时 koa-body 中间件不生效</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">bodyParser</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">bodyParser</span><span style="color: #C9D1D9">.</span><span style="color: #FFA657">IKoaBodyOptions</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">createServer</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> (</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">cb</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> (</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">req</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">IncomingMessage</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">|</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Http2ServerRequest</span><span style="color: #C9D1D9">,</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">res</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">ServerResponse</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">|</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Http2ServerResponse</span></span>
<span><span style="color: #C9D1D9"> ) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">void</span></span>
<span><span style="color: #C9D1D9"> ) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Server</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">beforeLoad</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> (</span><span style="color: #FFA657">uma</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Uma</span><span style="color: #C9D1D9">) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">void</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">afterLoaded</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> (</span><span style="color: #FFA657">uma</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Uma</span><span style="color: #C9D1D9">) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">void</span></span>
<span><span style="color: #C9D1D9">}</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br><span>10</span><br><span>11</span><br><span>12</span><br><span>13</span><br><span>14</span><br><span>15</span><br><span>16</span><br><span>17</span><br><span>18</span><br><span>19</span><br><span>20</span><br><span>21</span><br><span>22</span><br><span>23</span><br><span>24</span><br></div></div><h3 id="uma-app" tabindex="-1"> uma.app</h3>
<p><code>Koa Application</code>对象的实例,初始化时生成</p>
<h3 id="uma-start-port-number-8058" tabindex="-1"> uma.start(port: number = 8058)</h3>
<p><code>Uma</code>启动方法,需要在初始化时调用,默认端口是 8058</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #8B949E">// app.ts</span></span>
<span><span style="color: #8B949E">// ===> 调用start方法启动项目</span></span>
<span><span style="color: #C9D1D9">uma.</span><span style="color: #D2A8FF">start</span><span style="color: #C9D1D9">(</span><span style="color: #79C0FF">8058</span><span style="color: #C9D1D9">)</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br></div></div><h3 id="beforeload-afterload" tabindex="-1"> beforeLoad, afterLoad</h3>
<p>服务启动前后的钩子函数,传入当前 uma 实例</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #FF7B72">const</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">uma</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> Uma.</span><span style="color: #D2A8FF">instance</span><span style="color: #C9D1D9">({</span></span>
<span><span style="color: #C9D1D9"> ROOT: __dirname,</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">beforeLoad</span><span style="color: #C9D1D9">(</span><span style="color: #FFA657">uma</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Uma</span><span style="color: #C9D1D9">) {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 服务开始启动</span></span>
<span><span style="color: #C9D1D9"> },</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">afterLoad</span><span style="color: #C9D1D9">(</span><span style="color: #FFA657">uma</span><span style="color: #FF7B72">:</span><span style="color: #C9D1D9"> </span><span style="color: #FFA657">Uma</span><span style="color: #C9D1D9">) {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #8B949E">// 服务启动完成</span></span>
<span><span style="color: #C9D1D9"> },</span></span>
<span><span style="color: #C9D1D9">})</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br></div></div><h2 id="静态方法" tabindex="-1"> 静态方法</h2>
<h3 id="instance" tabindex="-1"> instance</h3>
<p>获取/实例化 Uma,实例化必须传参,获取实例化后的 Uma 不用传参</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static </span><span style="color: #D2A8FF">instance</span><span style="color: #C9D1D9">(options</span><span style="color: #FF7B72">?:</span><span style="color: #C9D1D9"> TUmaOption): Uma;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="获取运行环境" tabindex="-1"> 获取运行环境</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">env</span><span style="color: #C9D1D9">(): string;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="获取-app" tabindex="-1"> 获取 app</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">app</span><span style="color: #C9D1D9">(): Koa</span><span style="color: #FF7B72"><</span><span style="color: #C9D1D9">Koa.DefaultState, IContext</span><span style="color: #FF7B72">></span><span style="color: #C9D1D9">;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="获取-server" tabindex="-1"> 获取 server</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">server</span><span style="color: #C9D1D9">(): http.Server </span><span style="color: #FF7B72">|</span><span style="color: #C9D1D9"> https.Server;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="options" tabindex="-1"> options</h3>
<p>获取运行 Uma 的参数</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">options</span><span style="color: #C9D1D9">(): TUmaOption;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="config" tabindex="-1"> config</h3>
<p>获取所有 Uma 的配置</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">config</span><span style="color: #C9D1D9">(): TConfig;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="获取插件配置" tabindex="-1"> 获取插件配置</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">pluginConfig</span><span style="color: #C9D1D9">(): {</span></span>
<span><span style="color: #C9D1D9"> [pluginName: string]: boolean </span><span style="color: #FF7B72">|</span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">import</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">"../types/TPluginConfig"</span><span style="color: #C9D1D9">).TPluginConfig;</span></span>
<span><span style="color: #C9D1D9"> };</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br></div></div><h3 id="获取生效的-plugin-key" tabindex="-1"> 获取生效的 plugin key</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">pluginKeys</span><span style="color: #C9D1D9">(): any[];</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="或者某个插件的参数" tabindex="-1"> 或者某个插件的参数</h3>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static </span><span style="color: #D2A8FF">pluginOptions</span><span style="color: #C9D1D9">(pluginName: string): object;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="context" tabindex="-1"> context</h3>
<p>获取 context,可以对 context 进行扩展等。实例化之后就是我们使用的 ctx</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">context</span><span style="color: #C9D1D9">(): Koa.BaseContext </span><span style="color: #FF7B72">&</span><span style="color: #C9D1D9"> IContext;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div><h3 id="controllersinfo" tabindex="-1"> controllersInfo</h3>
<p>获取实例化之后的 controller 信息,包括 controller、route 等</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9"> static get </span><span style="color: #D2A8FF">controllersInfo</span><span style="color: #C9D1D9">(): IterableIterator</span><span style="color: #FF7B72"><import</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">".."</span><span style="color: #C9D1D9">).TControllerInfo</span><span style="color: #FF7B72">></span><span style="color: #C9D1D9">;</span></span>
<span></span></code></pre><div><span>1</span><br></div></div>]]></content>
</entry>
<entry>
<title type="html">Uma 与 Koa</title>
<id>https://umajs.github.io/newbieGuide/Uma.html</id>
<link href="https://umajs.github.io/newbieGuide/Uma.html"/>
<updated>2023-03-17T10:20:25.164Z</updated>
<content type="html"><![CDATA[<h1 id="uma-与-koa" tabindex="-1"> Uma 与 Koa</h1>
<blockquote>
<p>使用客户端与服务端通用开发语言的问题是一直是开发者需要面临的问题,而 NodeJs 的出现使得 JavaScript 一跃成为最流行的 web 开发语言。各类 node web 框架层出不穷,其中不乏著名的 Express、Koa......</p>
</blockquote>
<h2 id="koa" tabindex="-1"> Koa</h2>
<p>Express 无疑是使用最广泛的 node 框架,从 github start 可以看出来其受欢迎的程度,但基于 ECMAScript 版本的变化,Express 很多功能受到 ES5 的约束,比如一直令人头疼的<a href="http://callbackhell.com/" target="_blank" rel="noopener noreferrer">Callback Hell</a>。</p>
<p>为解决一系列问题,<a href="https://github.com/tj" target="_blank" rel="noopener noreferrer">TJ</a>发现对 Express 进行重构似乎更加困难,于是就有了现在的 Koa。</p>
<h3 id="架构设计" tabindex="-1"> 架构设计</h3>
<p>Express 一体式的架构设计能够让开发者快速的搭建一个 node server,其自身集成了例如
<a href="https://expressjs.com/en/starter/static-files.html" target="_blank" rel="noopener noreferrer">static</a>、
<a href="https://expressjs.com/en/guide/routing.html" target="_blank" rel="noopener noreferrer">router</a>、
<a href="https://expressjs.com/en/guide/using-template-engines.html" target="_blank" rel="noopener noreferrer">views</a>
等功能,能够为开发者提供静态文件、路由方法、模板引擎等服务。庞大的社区也为其提供了众多中间件模块,其成熟稳定的生态环境是众多开发者选择的关键因素。但是这也使整个框架显得较为厚重,毕竟一部分功能开发者可能并不会使用到。</p>
<p>而 Koa 则是摒弃了原有思想,致力于实现一个轻量级应用框架,事实上它确实非常轻巧,只有大约 550 行代码。它将原有功能进行拆分,分包成各个模块,因此拥有大量有用的方法但占用空间很小,开发者可以根据需要进行引用。</p>
<h3 id="middleware" tabindex="-1"> Middleware</h3>
<p>核心设计的不同也使得 Koa 与 Express 风格的中间件不兼容,大量原社区资源无法直接利用。</p>
<ul>
<li><strong>模型</strong></li>
</ul>
<p>相比 Express 中间件执行的线性流程,Koa 采用堆栈形式的先进后出,可以更全面的对 HTTP 流程做出响应,下图为 Koa 洋葱模型:<br>
<img src="@source/../public/images/koaOnion.png" alt="Koa onion"></p>
<p>Express 中间件只有两个参数 request 与 response,Koa 2.x 比 Express 增加了一个上下文的对象
<a href="https://github.com/koajs/koa/blob/master/docs/api/context.md" target="_blank" rel="noopener noreferrer">Context</a>,
并且将 request 与 response 挂载在 context 上作为第一个参数传入。</p>
<p>在 Koa 中开发者可以很方便地对 ctx 对象进行拓展,并且在所有中间件中进行共享。</p>
<h3 id="error-handling" tabindex="-1"> Error handling</h3>
<p>Express 附带一个错误处理程序,但使用起来较为繁琐,对于异步代码需要手动调用 next 传递错误信息。<br>
Koa 配合 <code>try..catch..</code> 的错误处理方式便显得更加优雅。</p>
<div><pre style="background-color: #0d1117"><code><span><span style="color: #C9D1D9">app.</span><span style="color: #D2A8FF">use</span><span style="color: #C9D1D9">(</span><span style="color: #FF7B72">async</span><span style="color: #C9D1D9"> (</span><span style="color: #FFA657">ctx</span><span style="color: #C9D1D9">, </span><span style="color: #FFA657">next</span><span style="color: #C9D1D9">) </span><span style="color: #FF7B72">=></span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">try</span><span style="color: #C9D1D9"> {</span></span>
<span><span style="color: #C9D1D9"> </span><span style="color: #FF7B72">await</span><span style="color: #C9D1D9"> </span><span style="color: #D2A8FF">next</span><span style="color: #C9D1D9">()</span></span>
<span><span style="color: #C9D1D9"> } </span><span style="color: #FF7B72">catch</span><span style="color: #C9D1D9"> (err) {</span></span>
<span><span style="color: #C9D1D9"> ctx.status </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> err.status </span><span style="color: #FF7B72">||</span><span style="color: #C9D1D9"> </span><span style="color: #79C0FF">500</span></span>
<span><span style="color: #C9D1D9"> ctx.body </span><span style="color: #FF7B72">=</span><span style="color: #C9D1D9"> { info: </span><span style="color: #A5D6FF">'error...'</span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #C9D1D9"> ctx.app.</span><span style="color: #D2A8FF">emit</span><span style="color: #C9D1D9">(</span><span style="color: #A5D6FF">'error'</span><span style="color: #C9D1D9">, err, </span><span style="color: #79C0FF">this</span><span style="color: #C9D1D9">)</span></span>
<span><span style="color: #C9D1D9"> }</span></span>
<span><span style="color: #C9D1D9">})</span></span>
<span></span></code></pre><div><span>1</span><br><span>2</span><br><span>3</span><br><span>4</span><br><span>5</span><br><span>6</span><br><span>7</span><br><span>8</span><br><span>9</span><br></div></div><h2 id="uma" tabindex="-1"> Uma</h2>