├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md ├── demos ├── 01.js ├── 02.js ├── 03.js ├── 04.js ├── 05.js ├── 06.js ├── 07.js ├── 08.js ├── 09.js ├── 10.js ├── 11.js ├── 12.js ├── 13.js ├── 14.js ├── 15.js ├── 16.js ├── 17.js ├── 18.js ├── 19.js ├── 20.js ├── 21.js └── template.html ├── logo.png ├── package-lock.json └── package.json /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8.4 2 | COPY . /app 3 | WORKDIR /app 4 | RUN ["npm", "install"] 5 | EXPOSE 3000/tcp 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A collection of simple demos of [Koa](http://koajs.com/), a web application framework for Node. 2 | 3 |  4 | 5 | ## How to use 6 | 7 | First of all, check your Node version. 8 | 9 | ```bash 10 | $ node -v 11 | v8.0.0 12 | ``` 13 | 14 | Koa requires node v7.6.0+. If your version is older than that, upgrade Node first. 15 | 16 | Then clone the repo (or download [zip file](https://github.com/ruanyf/koa-demos/archive/master.zip)). 17 | 18 | ```bash 19 | $ git clone git@github.com:ruanyf/koa-demos.git 20 | ``` 21 | 22 | Install the dependencies. 23 | 24 | ```bash 25 | $ cd koa-demos 26 | $ npm install 27 | ``` 28 | 29 | Now play with the [source files](https://github.com/ruanyf/koa-demos/tree/master/demos) under the demos directory. 30 | 31 | ## Index 32 | 33 | 1. Basics 34 | - [Start a server](#demo01-start-a-server) 35 | - [Hello World](#demo02-hello-world) 36 | - [Response type](#demo03-response-type) 37 | - [Use a template](#demo04-use-a-template) 38 | 1. Router 39 | - [Simple router](#demo05-simple-router) 40 | - [Koa-route](#demo06-koa-route) 41 | - [Static assets](#demo12-static-assets) 42 | - [Response redirecting](#demo13-response-redirecting) 43 | 1. Middleware 44 | - [Logger](#demo07-logger) 45 | - [Middleware](#demo08-middleware) 46 | - [Middleware stack](#demo09-middleware-stack) 47 | - [Async middleware](#demo10-async-middleware) 48 | - [Compose multi middlewares](#demo11-compose-multi-middlewares) 49 | 1. Error handling 50 | - [500 error](#demo14-500-error) 51 | - [404 error](#demo15-404-error) 52 | - [Error handling](#demo16-error-handling) 53 | - [Error listener](#demo17-error-listener) 54 | - [Error emitting](#demo18-error-emitting) 55 | 1. Web app 56 | - [Cookies](#demo19-cookies) 57 | - [Form](#demo20-form) 58 | - [Upload](#demo21-upload) 59 | 60 | ## Demo01: start a server 61 | 62 | Starting a server with Koa is very easy. Only 3 lines. 63 | 64 | ```javascript 65 | // demos/01.js 66 | const Koa = require('koa'); 67 | const app = new Koa(); 68 | 69 | app.listen(3000); 70 | ``` 71 | 72 | Run the demo. 73 | 74 | ```bash 75 | $ node demos/01.js 76 | ``` 77 | 78 | Visit http://127.0.0.1:3000 . You should see nothing but 'Not Found' in the page, since we haven't add any content. 79 | 80 | ## Demo02: Hello World 81 | 82 | Koa provides a Context object encapsulating HTTP request and response. 83 | 84 | > - `context.request`: a Request object, representing as the incoming http message. 85 | > - `context.response`: a Response object, representing the corresponding response to that message. 86 | 87 | `Context.response.body` is the data responsing to the visitor. 88 | 89 | ```javascript 90 | // demos/02.js 91 | const Koa = require('koa'); 92 | const app = new Koa(); 93 | 94 | const main = ctx => { 95 | ctx.response.body = 'Hello World'; 96 | }; 97 | 98 | app.use(main); 99 | app.listen(3000); 100 | ``` 101 | 102 | Run the demo. 103 | 104 | ```bash 105 | $ node demos/02.js 106 | ``` 107 | 108 | Visit http://127.0.0.1:3000 . Now you should see 'Hello World' in the page. 109 | 110 | ## Demo03: response type 111 | 112 | `ctx.request.accepts` checks HTTP request head's `Accept` field. According to the client's accept preference, server could send out responses of different types. 113 | 114 | ```javascript 115 | // demos/03.js 116 | const Koa = require('koa'); 117 | const app = new Koa(); 118 | 119 | const main = ctx => { 120 | if (ctx.request.accepts('xml')) { 121 | ctx.response.type = 'xml'; 122 | ctx.response.body = 'Hello World'; 123 | } else if (ctx.request.accepts('json')) { 124 | ctx.response.type = 'json'; 125 | ctx.response.body = { data: 'Hello World' }; 126 | } else if (ctx.request.accepts('html')) { 127 | ctx.response.type = 'html'; 128 | ctx.response.body = '
Hello World
'; 129 | } else { 130 | ctx.response.type = 'text'; 131 | ctx.response.body = 'Hello World'; 132 | } 133 | }; 134 | 135 | app.use(main); 136 | app.listen(3000); 137 | ``` 138 | 139 | Run the demo. 140 | 141 | ```bash 142 | $ node demos/03.js 143 | ``` 144 | 145 | Visit http://127.0.0.1:3000 . What you see depends on the `Accept` field of HTTP request header. In most cases, the content will be a XML document. 146 | 147 | ## Demo04: use a template 148 | 149 | A template file could be used as the response sending to the client. 150 | 151 | ```javascript 152 | // demos/04.js 153 | const fs = require('fs'); 154 | const Koa = require('koa'); 155 | const app = new Koa(); 156 | 157 | const main = ctx => { 158 | ctx.response.type = 'html'; 159 | ctx.response.body = fs.createReadStream('./demos/template.html'); 160 | }; 161 | 162 | app.use(main); 163 | app.listen(3000); 164 | ``` 165 | 166 | Run the demo. 167 | 168 | ```bash 169 | $ node demos/04.js 170 | ``` 171 | 172 | Visit http://127.0.0.1:3000 . You will see the content of the template file. 173 | 174 | ## Demo05: simple router 175 | 176 | `ctx.request.path` is the requestd path. We could use it to implement a simple router. 177 | 178 | ```javascript 179 | // demos/05.js 180 | const Koa = require('koa'); 181 | const app = new Koa(); 182 | 183 | const main = ctx => { 184 | if (ctx.request.path !== '/') { 185 | ctx.response.type = 'html'; 186 | ctx.response.body = 'Index Page'; 187 | } else { 188 | ctx.response.body = 'Hello World'; 189 | } 190 | }; 191 | 192 | app.use(main); 193 | app.listen(3000); 194 | ``` 195 | 196 | Run the demo. 197 | 198 | ```bash 199 | $ node demos/05.js 200 | ``` 201 | 202 | Visit http://127.0.0.1:3000/about . You could click the link to the Index page. 203 | 204 | ## Demo06: koa-route 205 | 206 | [`koa-route`](https://www.npmjs.com/package/koa-route) package is a more elegant and useful way to implement the router functionality. 207 | 208 | ```javascript 209 | // demos/06.js 210 | const Koa = require('koa'); 211 | const route = require('koa-route'); 212 | const app = new Koa(); 213 | 214 | const about = ctx => { 215 | ctx.response.type = 'html'; 216 | ctx.response.body = 'Index Page'; 217 | }; 218 | 219 | const main = ctx => { 220 | ctx.response.body = 'Hello World'; 221 | }; 222 | 223 | app.use(route.get('/', main)); 224 | app.use(route.get('/about', about)); 225 | 226 | app.listen(3000); 227 | ``` 228 | 229 | Run the demo. 230 | 231 | ```bash 232 | $ node demos/06.js 233 | ``` 234 | 235 | Visit http://127.0.0.1:3000/about . You could click the link to the Index page. 236 | 237 | ## Demo07: logger 238 | 239 | Logging is easy. Adding a line into the `main` function. 240 | 241 | ```javascript 242 | // demos/07.js 243 | const Koa = require('koa'); 244 | const app = new Koa(); 245 | 246 | const main = ctx => { 247 | console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`); 248 | ctx.response.body = 'Hello World'; 249 | }; 250 | 251 | app.use(main); 252 | app.listen(3000); 253 | ``` 254 | 255 | Run the demo. 256 | 257 | ```bash 258 | $ node demos/07.js 259 | ``` 260 | 261 | Visit http://127.0.0.1:3000 . You will see the logging info in console. 262 | 263 | ## Demo08: middleware 264 | 265 | The logger in the previous demo could be taken out as a separate function which we call it a middleware. Because a middleware is like a middle layer between HTTP request and HTTP response to process the data. 266 | 267 | ```javascript 268 | // demos/08.js 269 | const Koa = require('koa'); 270 | const app = new Koa(); 271 | 272 | const logger = (ctx, next) => { 273 | console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`); 274 | next(); 275 | } 276 | 277 | const main = ctx => { 278 | ctx.response.body = 'Hello World'; 279 | }; 280 | 281 | app.use(logger); 282 | app.use(main); 283 | app.listen(3000); 284 | ``` 285 | 286 | Each middleware receives a Koa Context object and a `next` function as parameters. Calling `next` function will pass the execution to the next middleware. 287 | 288 | `app.use()` is used to load middlewares. All functionalities in Koa are achieved by middlewares. 289 | 290 | Run the demo. 291 | 292 | ```bash 293 | $ node demos/08.js 294 | ``` 295 | 296 | Visit http://127.0.0.1:3000 . You will see the logging info in console. 297 | 298 | ## Demo09: middleware stack 299 | 300 | Multi middlewares form a middle stack. The most outer middleware is executed first, then passes the execution to the next middleware. And the most inner middleware is executed last, then returns the execution to the previous middleware. It is just like a first-in-last-out stack. 301 | 302 | ```javascript 303 | // demos/09.js 304 | const Koa = require('koa'); 305 | const app = new Koa(); 306 | 307 | const one = (ctx, next) => { 308 | console.log('>> one'); 309 | next(); 310 | console.log('<< one'); 311 | } 312 | 313 | const two = (ctx, next) => { 314 | console.log('>> two'); 315 | next(); 316 | console.log('<< two'); 317 | } 318 | 319 | const three = (ctx, next) => { 320 | console.log('>> three'); 321 | next(); 322 | console.log('<< three'); 323 | } 324 | 325 | app.use(one); 326 | app.use(two); 327 | app.use(three); 328 | 329 | app.listen(3000); 330 | ``` 331 | 332 | Run the demo. 333 | 334 | ```bash 335 | $ node demos/09.js 336 | ``` 337 | 338 | Visit http://127.0.0.1:3000 . You will see the following result in console. 339 | 340 | ```bash 341 | >> one 342 | >> two 343 | >> three 344 | << three 345 | << two 346 | << one 347 | ``` 348 | 349 | As a exercise, commenting the line of `next()` in the middleware `two`, you will find the execution will not be passed down. 350 | 351 | ## Demo10: async middleware 352 | 353 | If there are async operations in a middleware, you have to use async middleware, i.e. use a async function as middleware. 354 | 355 | ```javascript 356 | const fs = require('fs.promised'); 357 | const Koa = require('koa'); 358 | const app = new Koa(); 359 | 360 | const main = async function (ctx, next) { 361 | ctx.response.type = 'html'; 362 | ctx.response.body = await fs.readFile('./demos/template.html', 'utf8'); 363 | }; 364 | 365 | app.use(main); 366 | app.listen(3000); 367 | ``` 368 | 369 | In above codes, `fs.readFile` is a async operation, so you have to write `await fs.readFile()`, then put it in a async function. 370 | 371 | Run the demo. 372 | 373 | ```bash 374 | $ node demos/10.js 375 | ``` 376 | 377 | Visit http://127.0.0.1:3000 . You will see the content of the template file. 378 | 379 | ## Demo11: compose multi middlewares 380 | 381 | [`koa-compose`](https://www.npmjs.com/package/koa-compose) package is used to compose multi middlewares into one. 382 | 383 | ```javascript 384 | // demos/11.js 385 | const Koa = require('koa'); 386 | const compose = require('koa-compose'); 387 | const app = new Koa(); 388 | 389 | const logger = (ctx, next) => { 390 | console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`); 391 | next(); 392 | } 393 | 394 | const main = ctx => { 395 | ctx.response.body = 'Hello World'; 396 | }; 397 | 398 | const middlewares = compose([logger, main]); 399 | 400 | app.use(middlewares); 401 | app.listen(3000); 402 | ``` 403 | 404 | Run the demo. 405 | 406 | ```bash 407 | $ node demos/11.js 408 | ``` 409 | 410 | Visit http://127.0.0.1:3000 . You will see the logging info in console. 411 | 412 | ## Demo12: static assets 413 | 414 | [`koa-static`](https://www.npmjs.com/package/koa-static) package could be used to serve static assets. 415 | 416 | ```javascript 417 | // demos/12.js 418 | const Koa = require('koa'); 419 | const app = new Koa(); 420 | const path = require('path'); 421 | const serve = require('koa-static'); 422 | 423 | const main = serve(path.join(__dirname)); 424 | 425 | app.use(main); 426 | app.listen(3000); 427 | ``` 428 | 429 | Run the demo. 430 | 431 | ```bash 432 | $ node demos/12.js 433 | ``` 434 | 435 | Visit http://127.0.0.1:3000/12.js . you will see the above code. 436 | 437 | ## Demo13: response redirecting 438 | 439 | `ctx.response.redirect()` redirects visitor into another page. 440 | 441 | ```javascript 442 | // demos/13.js 443 | const Koa = require('koa'); 444 | const route = require('koa-route'); 445 | const app = new Koa(); 446 | 447 | const redirect = ctx => { 448 | ctx.response.redirect('/'); 449 | ctx.response.body = 'Index Page'; 450 | }; 451 | 452 | const main = ctx => { 453 | ctx.response.body = 'Hello World'; 454 | }; 455 | 456 | app.use(route.get('/', main)); 457 | app.use(route.get('/redirect', redirect)); 458 | 459 | app.use(main); 460 | app.listen(3000); 461 | ``` 462 | 463 | Run the demo. 464 | 465 | ```bash 466 | $ node demos/13.js 467 | ``` 468 | 469 | Visit http://127.0.0.1:3000/redirect. The browser will be redirected to the root path. 470 | 471 | ## Demo14: 500 error 472 | 473 | `ctx.throw()` throws an error response (status code 4xx / 5xx) to visitor. 474 | 475 | ```javascript 476 | // demos/14.js 477 | const Koa = require('koa'); 478 | const app = new Koa(); 479 | 480 | const main = ctx => { 481 | ctx.throw(500); 482 | }; 483 | 484 | app.use(main); 485 | app.listen(3000); 486 | ``` 487 | 488 | Run the demo. 489 | 490 | ```bash 491 | $ node demos/14.js 492 | ``` 493 | 494 | visit http://127.0.0.1:3000. You will see a 500 error page of "Internal Server Error". 495 | 496 | ## Demo15: 404 error 497 | 498 | Setting `ctx.response.status` as 404 has the same effect as `ctx.throw(404)`. 499 | 500 | ```javascript 501 | const Koa = require('koa'); 502 | const app = new Koa(); 503 | 504 | const main = ctx => { 505 | ctx.response.status = 404; 506 | ctx.response.body = 'Page Not Found'; 507 | }; 508 | 509 | app.use(main); 510 | app.listen(3000); 511 | ``` 512 | 513 | Run the demo. 514 | 515 | ```bash 516 | $ node demos/15.js 517 | ``` 518 | 519 | Visit http://127.0.0.1:3000 . You will see a 404 error page of 'Page Not Found'. 520 | 521 | ## Demo16: error handling 522 | 523 | A error-handling middleware could be put on the top of middleware stack to catch the thrown errors. 524 | 525 | ```javascript 526 | // demos/16.js 527 | const Koa = require('koa'); 528 | const app = new Koa(); 529 | 530 | const handler = async (ctx, next) => { 531 | try { 532 | await next(); 533 | } catch (err) { 534 | ctx.response.status = err.statusCode || err.status || 500; 535 | ctx.response.body = { 536 | message: err.message 537 | }; 538 | } 539 | }; 540 | 541 | const main = ctx => { 542 | ctx.throw(500); 543 | }; 544 | 545 | app.use(handler); 546 | app.use(main); 547 | app.listen(3000); 548 | ``` 549 | 550 | Run the demo. 551 | 552 | ```bash 553 | $ node demos/16.js 554 | ``` 555 | 556 | Visit http://127.0.0.1:3000 . You will see a 500 page of `{"message":"Internal Server Error"}`. 557 | 558 | ## Demo17: error listener 559 | 560 | You could listen to `error` event. 561 | 562 | ```javascript 563 | // demos/17.js 564 | const Koa = require('koa'); 565 | const app = new Koa(); 566 | 567 | const main = ctx => { 568 | ctx.throw(500); 569 | }; 570 | 571 | app.on('error', (err, ctx) => { 572 | console.error('server error', err); 573 | }); 574 | 575 | app.use(main); 576 | app.listen(3000); 577 | ``` 578 | 579 | Run the demo. 580 | 581 | ```bash 582 | $ node demos/17.js 583 | ``` 584 | 585 | Visit http://127.0.0.1:3000 . You will see `server error` in the command line console. 586 | 587 | ## Demo18: error emitting 588 | 589 | A error listener does not work under all cases. If an error is caught and not thrown again, it will not be passed to the error listener. 590 | 591 | ```javascript 592 | // demos/18.js` 593 | const Koa = require('koa'); 594 | const app = new Koa(); 595 | 596 | const handler = async (ctx, next) => { 597 | try { 598 | await next(); 599 | } catch (err) { 600 | ctx.response.status = err.statusCode || err.status || 500; 601 | ctx.response.type = 'html'; 602 | ctx.response.body = 'Something wrong, please contact administrator.
'; 603 | ctx.app.emit('error', err, ctx); 604 | } 605 | }; 606 | 607 | const main = ctx => { 608 | ctx.throw(500); 609 | }; 610 | 611 | app.on('error', function(err) { 612 | console.log('logging error ', err.message); 613 | console.log(err); 614 | }); 615 | 616 | app.use(handler); 617 | app.use(main); 618 | app.listen(3000); 619 | ``` 620 | 621 | In above codes, `ctx.app.emit()` is used to emit an `error` event. 622 | 623 | Run the demo. 624 | 625 | ```bash 626 | $ node demos/18.js 627 | ``` 628 | 629 | Visit http://127.0.0.1:3000 . You will see `logging error ` in the command line console. 630 | 631 | ## Demo19: cookies 632 | 633 | `ctx.cookies` is used to read/write cookies. 634 | 635 | ```javascript 636 | // demos/19.js 637 | const Koa = require('koa'); 638 | const app = new Koa(); 639 | 640 | const main = function(ctx) { 641 | const n = Number(ctx.cookies.get('view') || 0) + 1; 642 | ctx.cookies.set('view', n); 643 | ctx.response.body = n + ' views'; 644 | } 645 | 646 | app.use(main); 647 | app.listen(3000); 648 | ``` 649 | 650 | Run the demo. 651 | 652 | ```bash 653 | $ node demos/19.js 654 | ``` 655 | 656 | Visit http://127.0.0.1:3000 and refresh the page, and you should see `1 views` at first, then `2 views`. 657 | 658 | ## Demo20: form 659 | 660 | [`koa-body`](https://www.npmjs.com/package/koa-body) package is used to parse the body carried by a POST request. 661 | 662 | ```javascript 663 | // demos/20.js 664 | const Koa = require('koa'); 665 | const koaBody = require('koa-body'); 666 | const app = new Koa(); 667 | 668 | const main = async function(ctx) { 669 | const body = ctx.request.body; 670 | if (!body.name) ctx.throw(400, '.name required'); 671 | ctx.body = { name: body.name }; 672 | }; 673 | 674 | app.use(koaBody()); 675 | app.use(main); 676 | app.listen(3000); 677 | ``` 678 | 679 | Run the demo. 680 | 681 | ```bash 682 | $ node demos/20.js 683 | ``` 684 | 685 | Open another command line window, and run the following command. 686 | 687 | ```bash 688 | $ curl -X POST --data "name=Jack" 127.0.0.1:3000 689 | {"name":"Jack"} 690 | 691 | $ curl -X POST --data "name" 127.0.0.1:3000 692 | name required 693 | ``` 694 | 695 | ## Demo21: upload 696 | 697 | [`koa-body`](https://www.npmjs.com/package/koa-body) package could process the upload files as well. 698 | 699 | ```javascript 700 | // demos/21.js 701 | const os = require('os'); 702 | const path = require('path'); 703 | const Koa = require('koa'); 704 | const fs = require('fs'); 705 | const koaBody = require('koa-body'); 706 | 707 | const app = new Koa(); 708 | 709 | const main = async function(ctx) { 710 | const tmpdir = os.tmpdir(); 711 | const filePaths = []; 712 | const files = ctx.request.body.files || {}; 713 | 714 | for (let key in files) { 715 | const file = files[key]; 716 | const filePath = path.join(tmpdir, file.name); 717 | const reader = fs.createReadStream(file.path); 718 | const writer = fs.createWriteStream(filePath); 719 | reader.pipe(writer); 720 | filePaths.push(filePath); 721 | } 722 | 723 | ctx.body = filePaths; 724 | }; 725 | 726 | app.use(koaBody({ multipart: true })); 727 | app.use(main); 728 | app.listen(3000); 729 | ``` 730 | 731 | Run the demo. 732 | 733 | ```bash 734 | $ node demos/21.js 735 | ``` 736 | 737 | Open another command line window, and run the following command to upload a file. 738 | 739 | ```bash 740 | $ curl --form upload=@/path/to/file http://127.0.0.1:3000 741 | ["/tmp/file"] 742 | ``` 743 | 744 | ## Useful links 745 | 746 | - [koa workshop](https://github.com/koajs/workshop) 747 | - [kick-off-koa](https://github.com/koajs/kick-off-koa) 748 | - [Koa Examples](https://github.com/koajs/examples) 749 | 750 | -------------------------------------------------------------------------------- /demos/01.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | app.listen(3000); 5 | -------------------------------------------------------------------------------- /demos/02.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const main = ctx => { 5 | ctx.response.body = 'Hello World'; 6 | }; 7 | 8 | app.use(main); 9 | app.listen(3000); 10 | -------------------------------------------------------------------------------- /demos/03.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const main = ctx => { 5 | if (ctx.request.accepts('xml')) { 6 | ctx.response.type = 'xml'; 7 | ctx.response.body = 'Hello World'; 8 | } else if (ctx.request.accepts('json')) { 9 | ctx.response.type = 'json'; 10 | ctx.response.body = { data: 'Hello World' }; 11 | } else if (ctx.request.accepts('html')) { 12 | ctx.response.type = 'html'; 13 | ctx.response.body = 'Hello World
'; 14 | } else { 15 | ctx.response.type = 'text'; 16 | ctx.response.body = 'Hello World'; 17 | } 18 | }; 19 | 20 | app.use(main); 21 | app.listen(3000); 22 | -------------------------------------------------------------------------------- /demos/04.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const Koa = require('koa'); 3 | const app = new Koa(); 4 | 5 | const main = ctx => { 6 | ctx.response.type = 'html'; 7 | ctx.response.body = fs.createReadStream('./demos/template.html'); 8 | }; 9 | 10 | app.use(main); 11 | app.listen(3000); 12 | -------------------------------------------------------------------------------- /demos/05.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const main = ctx => { 5 | if (ctx.request.path !== '/') { 6 | ctx.response.type = 'html'; 7 | ctx.response.body = 'Index Page'; 8 | } else { 9 | ctx.response.body = 'Hello World'; 10 | } 11 | }; 12 | 13 | app.use(main); 14 | app.listen(3000); 15 | -------------------------------------------------------------------------------- /demos/06.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const route = require('koa-route'); 3 | const app = new Koa(); 4 | 5 | const about = ctx => { 6 | ctx.response.type = 'html'; 7 | ctx.response.body = 'Index Page'; 8 | }; 9 | 10 | const main = ctx => { 11 | ctx.response.body = 'Hello World'; 12 | }; 13 | 14 | app.use(route.get('/', main)); 15 | app.use(route.get('/about', about)); 16 | 17 | app.listen(3000); 18 | -------------------------------------------------------------------------------- /demos/07.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const main = ctx => { 5 | console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`); 6 | ctx.response.body = 'Hello World'; 7 | }; 8 | 9 | app.use(main); 10 | app.listen(3000); 11 | -------------------------------------------------------------------------------- /demos/08.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const logger = (ctx, next) => { 5 | console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`); 6 | next(); 7 | } 8 | 9 | const main = ctx => { 10 | ctx.response.body = 'Hello World'; 11 | }; 12 | 13 | app.use(logger); 14 | app.use(main); 15 | app.listen(3000); 16 | -------------------------------------------------------------------------------- /demos/09.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const one = (ctx, next) => { 5 | console.log('>> one'); 6 | next(); 7 | console.log('<< one'); 8 | } 9 | 10 | const two = (ctx, next) => { 11 | console.log('>> two'); 12 | next(); 13 | console.log('<< two'); 14 | } 15 | 16 | const three = (ctx, next) => { 17 | console.log('>> three'); 18 | next(); 19 | console.log('<< three'); 20 | } 21 | 22 | app.use(one); 23 | app.use(two); 24 | app.use(three); 25 | 26 | app.listen(3000); 27 | -------------------------------------------------------------------------------- /demos/10.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs.promised'); 2 | const Koa = require('koa'); 3 | const app = new Koa(); 4 | 5 | const main = async function (ctx, next) { 6 | ctx.response.type = 'html'; 7 | ctx.response.body = await fs.readFile('./demos/template.html', 'utf8'); 8 | }; 9 | 10 | app.use(main); 11 | app.listen(3000); 12 | -------------------------------------------------------------------------------- /demos/11.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const compose = require('koa-compose'); 3 | const app = new Koa(); 4 | 5 | const logger = (ctx, next) => { 6 | console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`); 7 | next(); 8 | } 9 | 10 | const main = ctx => { 11 | ctx.response.body = 'Hello World'; 12 | }; 13 | 14 | const middlewares = compose([logger, main]); 15 | 16 | app.use(middlewares); 17 | app.listen(3000); 18 | -------------------------------------------------------------------------------- /demos/12.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | const path = require('path'); 4 | const serve = require('koa-static'); 5 | 6 | const main = serve(path.join(__dirname)); 7 | 8 | app.use(main); 9 | app.listen(3000); 10 | -------------------------------------------------------------------------------- /demos/13.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const route = require('koa-route'); 3 | const app = new Koa(); 4 | 5 | const redirect = ctx => { 6 | ctx.response.redirect('/'); 7 | }; 8 | 9 | const main = ctx => { 10 | ctx.response.body = 'Hello World'; 11 | }; 12 | 13 | app.use(route.get('/', main)); 14 | app.use(route.get('/redirect', redirect)); 15 | 16 | app.use(main); 17 | app.listen(3000); 18 | -------------------------------------------------------------------------------- /demos/14.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const main = ctx => { 5 | ctx.throw(500); 6 | }; 7 | 8 | app.use(main); 9 | app.listen(3000); 10 | -------------------------------------------------------------------------------- /demos/15.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const main = ctx => { 5 | ctx.response.status = 404; 6 | ctx.response.body = 'Page Not Found'; 7 | }; 8 | 9 | app.use(main); 10 | app.listen(3000); 11 | -------------------------------------------------------------------------------- /demos/16.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const handler = async (ctx, next) => { 5 | try { 6 | await next(); 7 | } catch (err) { 8 | ctx.response.status = err.statusCode || err.status || 500; 9 | ctx.response.body = { 10 | message: err.message 11 | }; 12 | } 13 | }; 14 | 15 | const main = ctx => { 16 | ctx.throw(500); 17 | }; 18 | 19 | app.use(handler); 20 | app.use(main); 21 | app.listen(3000); 22 | -------------------------------------------------------------------------------- /demos/17.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const main = ctx => { 5 | ctx.throw(500); 6 | }; 7 | 8 | app.on('error', (err, ctx) => { 9 | console.error('server error', err); 10 | }); 11 | 12 | app.use(main); 13 | app.listen(3000); 14 | -------------------------------------------------------------------------------- /demos/18.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const handler = async (ctx, next) => { 5 | try { 6 | await next(); 7 | } catch (err) { 8 | ctx.response.status = err.statusCode || err.status || 500; 9 | ctx.response.type = 'html'; 10 | ctx.response.body = 'Something wrong, please contact administrator.
'; 11 | ctx.app.emit('error', err, ctx); 12 | } 13 | }; 14 | 15 | const main = ctx => { 16 | ctx.throw(500); 17 | }; 18 | 19 | app.on('error', function(err) { 20 | console.log('logging error ', err.message); 21 | console.log(err); 22 | }); 23 | 24 | app.use(handler); 25 | app.use(main); 26 | app.listen(3000); 27 | -------------------------------------------------------------------------------- /demos/19.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const main = function(ctx) { 5 | const n = Number(ctx.cookies.get('view') || 0) + 1; 6 | ctx.cookies.set('view', n); 7 | ctx.response.body = n + ' views'; 8 | } 9 | 10 | app.use(main); 11 | app.listen(3000); 12 | -------------------------------------------------------------------------------- /demos/20.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const koaBody = require('koa-body'); 3 | const app = new Koa(); 4 | 5 | const main = async function(ctx) { 6 | const body = ctx.request.body; 7 | if (!body.name) ctx.throw(400, '.name required'); 8 | ctx.body = { name: body.name }; 9 | }; 10 | 11 | app.use(koaBody()); 12 | app.use(main); 13 | app.listen(3000); 14 | -------------------------------------------------------------------------------- /demos/21.js: -------------------------------------------------------------------------------- 1 | const os = require('os'); 2 | const path = require('path'); 3 | const Koa = require('koa'); 4 | const fs = require('fs'); 5 | const koaBody = require('koa-body'); 6 | 7 | const app = new Koa(); 8 | 9 | const main = async function(ctx) { 10 | const tmpdir = os.tmpdir(); 11 | const filePaths = []; 12 | const files = ctx.request.body.files || {}; 13 | 14 | for (let key in files) { 15 | const file = files[key]; 16 | const filePath = path.join(tmpdir, file.name); 17 | const reader = fs.createReadStream(file.path); 18 | const writer = fs.createWriteStream(filePath); 19 | reader.pipe(writer); 20 | filePaths.push(filePath); 21 | } 22 | 23 | ctx.body = filePaths; 24 | }; 25 | 26 | app.use(koaBody({ multipart: true })); 27 | app.use(main); 28 | app.listen(3000); 29 | -------------------------------------------------------------------------------- /demos/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |