github.com/rpdict/ponzu@v0.10.1-0.20190226054626-477f29d6bf5e/docs/build/References/Overview/index.html (about) 1 2 <!DOCTYPE html> 3 <html lang="en" class="no-js"> 4 <head> 5 6 <meta charset="utf-8"> 7 <meta name="viewport" content="width=device-width,initial-scale=1"> 8 9 10 11 12 <link rel="shortcut icon" href="../../assets/images/favicon.png"> 13 14 <meta name="generator" content="mkdocs-0.16.3, mkdocs-material-1.6.1"> 15 16 17 18 <title>References in Ponzu</title> 19 20 21 22 <script src="../../assets/javascripts/modernizr-56ade86843.js"></script> 23 24 25 <link rel="stylesheet" href="../../assets/stylesheets/application-4d0d3f2fbf.css"> 26 27 <link rel="stylesheet" href="../../assets/stylesheets/application-f78e5cb881.palette.css"> 28 29 30 31 32 33 34 35 <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono"> 36 <style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style> 37 38 <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> 39 40 41 42 </head> 43 44 45 46 47 <body data-md-color-primary="grey" data-md-color-accent="light-blue"> 48 49 <svg class="md-svg"> 50 <defs> 51 52 53 <svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" viewBox="0 0 416 448" id="github"><path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19T128 352t-18.125-8.5-10.75-19T96 304t3.125-20.5 10.75-19T128 256t18.125 8.5 10.75 19T160 304zm160 0q0 10-3.125 20.5t-10.75 19T288 352t-18.125-8.5-10.75-19T256 304t3.125-20.5 10.75-19T288 256t18.125 8.5 10.75 19T320 304zm40 0q0-30-17.25-51T296 232q-10.25 0-48.75 5.25Q229.5 240 208 240t-39.25-2.75Q130.75 232 120 232q-29.5 0-46.75 21T56 304q0 22 8 38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 37.25-1.75t35-7.375 30.5-15 20.25-25.75T360 304zm56-44q0 51.75-15.25 82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5T212 416q-19.5 0-35.5-.75t-36.875-3.125-38.125-7.5-34.25-12.875T37 371.5t-21.5-28.75Q0 312 0 260q0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 30.875Q171.5 96 212 96q37 0 70 8 26.25-20.5 46.75-30.25T376 64q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 99.5z"/></svg> 54 55 </defs> 56 </svg> 57 <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer"> 58 <input class="md-toggle" data-md-toggle="search" type="checkbox" id="search"> 59 <label class="md-overlay" data-md-component="overlay" for="drawer"></label> 60 61 <header class="md-header" data-md-component="header"> 62 <nav class="md-header-nav md-grid"> 63 <div class="md-flex"> 64 <div class="md-flex__cell md-flex__cell--shrink"> 65 66 <a href="../.." title="Ponzu" class="md-logo md-header-nav__button"> 67 <img src="../../images/logo.png" width="24" height="24"> 68 </a> 69 70 </div> 71 <div class="md-flex__cell md-flex__cell--shrink"> 72 <label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label> 73 </div> 74 <div class="md-flex__cell md-flex__cell--stretch"> 75 <span class="md-flex__ellipsis md-header-nav__title"> 76 77 78 79 <span class="md-header-nav__parent"> 80 References 81 </span> 82 83 84 Overview 85 86 </span> 87 </div> 88 <div class="md-flex__cell md-flex__cell--shrink"> 89 90 <label class="md-icon md-icon--search md-header-nav__button" for="search"></label> 91 92 <div class="md-search" data-md-component="search"> 93 <label class="md-search__overlay" for="search"></label> 94 <div class="md-search__inner"> 95 <form class="md-search__form" name="search"> 96 <input type="text" class="md-search__input" name="query" required placeholder="Search" accesskey="s" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query"> 97 <label class="md-icon md-search__icon" for="search"></label> 98 <button type="reset" class="md-icon md-search__icon" data-md-component="reset">close</button> 99 </form> 100 <div class="md-search__output"> 101 <div class="md-search__scrollwrap" data-md-scrollfix> 102 <div class="md-search-result" data-md-component="result"> 103 <div class="md-search-result__meta" data-md-lang-result-none="No matching documents" data-md-lang-result-one="1 matching document" data-md-lang-result-other="# matching documents"> 104 Type to start searching 105 </div> 106 <ol class="md-search-result__list"></ol> 107 </div> 108 </div> 109 </div> 110 </div> 111 </div> 112 113 </div> 114 <div class="md-flex__cell md-flex__cell--shrink"> 115 <div class="md-header-nav__source"> 116 117 118 119 120 121 122 123 <a href="https://github.com/rpdict/ponzu" title="Go to repository" class="md-source" data-md-source="github"> 124 125 <div class="md-source__icon"> 126 <svg viewBox="0 0 24 24" width="24" height="24"> 127 <use xlink:href="#github" width="24" height="24"></use> 128 </svg> 129 </div> 130 131 <div class="md-source__repository"> 132 ponzu-cms/ponzu 133 </div> 134 </a> 135 136 137 </div> 138 </div> 139 </div> 140 </nav> 141 </header> 142 143 <div class="md-container"> 144 145 146 <main class="md-main"> 147 <div class="md-main__inner md-grid" data-md-component="container"> 148 149 150 <div class="md-sidebar md-sidebar--primary" data-md-component="navigation"> 151 <div class="md-sidebar__scrollwrap"> 152 <div class="md-sidebar__inner"> 153 <nav class="md-nav md-nav--primary" data-md-level="0"> 154 <label class="md-nav__title md-nav__title--site" for="drawer"> 155 156 <i class="md-logo md-nav__button"> 157 <img src="../../images/logo.png"> 158 </i> 159 160 Ponzu 161 </label> 162 163 <div class="md-nav__source"> 164 165 166 167 168 169 170 <a href="https://github.com/rpdict/ponzu" title="Go to repository" class="md-source" data-md-source="github"> 171 172 <div class="md-source__icon"> 173 <svg viewBox="0 0 24 24" width="24" height="24"> 174 <use xlink:href="#github" width="24" height="24"></use> 175 </svg> 176 </div> 177 178 <div class="md-source__repository"> 179 ponzu-cms/ponzu 180 </div> 181 </a> 182 183 </div> 184 185 <ul class="md-nav__list" data-md-scrollfix> 186 187 188 189 190 191 192 <li class="md-nav__item"> 193 <a href="../.." title="Home" class="md-nav__link"> 194 Home 195 </a> 196 </li> 197 198 199 200 201 202 203 204 <li class="md-nav__item md-nav__item--nested"> 205 206 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-2" type="checkbox" id="nav-2"> 207 208 <label class="md-nav__link" for="nav-2"> 209 CLI 210 </label> 211 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 212 <label class="md-nav__title" for="nav-2"> 213 CLI 214 </label> 215 <ul class="md-nav__list" data-md-scrollfix> 216 217 218 219 220 221 222 223 <li class="md-nav__item"> 224 <a href="../../CLI/General-Usage/" title="General Usage" class="md-nav__link"> 225 General Usage 226 </a> 227 </li> 228 229 230 231 232 233 234 235 <li class="md-nav__item"> 236 <a href="../../CLI/Generating-References/" title="Generating References" class="md-nav__link"> 237 Generating References 238 </a> 239 </li> 240 241 242 </ul> 243 </nav> 244 </li> 245 246 247 248 249 250 251 252 <li class="md-nav__item md-nav__item--nested"> 253 254 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-3" type="checkbox" id="nav-3"> 255 256 <label class="md-nav__link" for="nav-3"> 257 Content 258 </label> 259 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 260 <label class="md-nav__title" for="nav-3"> 261 Content 262 </label> 263 <ul class="md-nav__list" data-md-scrollfix> 264 265 266 267 268 269 270 271 <li class="md-nav__item"> 272 <a href="../../Content/An-Overview/" title="An Overview" class="md-nav__link"> 273 An Overview 274 </a> 275 </li> 276 277 278 279 280 281 282 283 <li class="md-nav__item"> 284 <a href="../../Content/Extending-Content/" title="Extending Content" class="md-nav__link"> 285 Extending Content 286 </a> 287 </li> 288 289 290 </ul> 291 </nav> 292 </li> 293 294 295 296 297 298 299 300 <li class="md-nav__item md-nav__item--nested"> 301 302 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-4" type="checkbox" id="nav-4"> 303 304 <label class="md-nav__link" for="nav-4"> 305 Form Fields 306 </label> 307 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 308 <label class="md-nav__title" for="nav-4"> 309 Form Fields 310 </label> 311 <ul class="md-nav__list" data-md-scrollfix> 312 313 314 315 316 317 318 319 <li class="md-nav__item"> 320 <a href="../../Form-Fields/HTML-Inputs/" title="HTML Inputs" class="md-nav__link"> 321 HTML Inputs 322 </a> 323 </li> 324 325 326 </ul> 327 </nav> 328 </li> 329 330 331 332 333 334 335 336 <li class="md-nav__item md-nav__item--nested"> 337 338 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-5" type="checkbox" id="nav-5"> 339 340 <label class="md-nav__link" for="nav-5"> 341 HTTP APIs 342 </label> 343 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 344 <label class="md-nav__title" for="nav-5"> 345 HTTP APIs 346 </label> 347 <ul class="md-nav__list" data-md-scrollfix> 348 349 350 351 352 353 354 355 <li class="md-nav__item"> 356 <a href="../../HTTP-APIs/Content/" title="Content" class="md-nav__link"> 357 Content 358 </a> 359 </li> 360 361 362 363 364 365 366 367 <li class="md-nav__item"> 368 <a href="../../HTTP-APIs/File-Metadata/" title="File Metadata" class="md-nav__link"> 369 File Metadata 370 </a> 371 </li> 372 373 374 375 376 377 378 379 <li class="md-nav__item"> 380 <a href="../../HTTP-APIs/Search/" title="Search" class="md-nav__link"> 381 Search 382 </a> 383 </li> 384 385 386 </ul> 387 </nav> 388 </li> 389 390 391 392 393 394 395 396 <li class="md-nav__item md-nav__item--nested"> 397 398 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6"> 399 400 <label class="md-nav__link" for="nav-6"> 401 Interfaces 402 </label> 403 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 404 <label class="md-nav__title" for="nav-6"> 405 Interfaces 406 </label> 407 <ul class="md-nav__list" data-md-scrollfix> 408 409 410 411 412 413 414 415 <li class="md-nav__item"> 416 <a href="../../Interfaces/API/" title="API" class="md-nav__link"> 417 API 418 </a> 419 </li> 420 421 422 423 424 425 426 427 <li class="md-nav__item"> 428 <a href="../../Interfaces/Editor/" title="Editor" class="md-nav__link"> 429 Editor 430 </a> 431 </li> 432 433 434 435 436 437 438 439 <li class="md-nav__item"> 440 <a href="../../Interfaces/Format/" title="Format" class="md-nav__link"> 441 Format 442 </a> 443 </li> 444 445 446 447 448 449 450 451 <li class="md-nav__item"> 452 <a href="../../Interfaces/Item/" title="Item" class="md-nav__link"> 453 Item 454 </a> 455 </li> 456 457 458 459 460 461 462 463 <li class="md-nav__item"> 464 <a href="../../Interfaces/Search/" title="Search" class="md-nav__link"> 465 Search 466 </a> 467 </li> 468 469 470 </ul> 471 </nav> 472 </li> 473 474 475 476 477 478 479 480 <li class="md-nav__item md-nav__item--nested"> 481 482 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-7" type="checkbox" id="nav-7"> 483 484 <label class="md-nav__link" for="nav-7"> 485 Ponzu Addons 486 </label> 487 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 488 <label class="md-nav__title" for="nav-7"> 489 Ponzu Addons 490 </label> 491 <ul class="md-nav__list" data-md-scrollfix> 492 493 494 495 496 497 498 499 <li class="md-nav__item"> 500 <a href="../../Ponzu-Addons/Creating-Addons/" title="Creating Addons" class="md-nav__link"> 501 Creating Addons 502 </a> 503 </li> 504 505 506 507 508 509 510 511 <li class="md-nav__item"> 512 <a href="../../Ponzu-Addons/Using-Addons/" title="Using Addons" class="md-nav__link"> 513 Using Addons 514 </a> 515 </li> 516 517 518 </ul> 519 </nav> 520 </li> 521 522 523 524 525 526 527 528 <li class="md-nav__item md-nav__item--nested"> 529 530 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-8" type="checkbox" id="nav-8"> 531 532 <label class="md-nav__link" for="nav-8"> 533 Quickstart 534 </label> 535 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 536 <label class="md-nav__title" for="nav-8"> 537 Quickstart 538 </label> 539 <ul class="md-nav__list" data-md-scrollfix> 540 541 542 543 544 545 546 547 <li class="md-nav__item"> 548 <a href="../../Quickstart/Overview/" title="Overview" class="md-nav__link"> 549 Overview 550 </a> 551 </li> 552 553 554 </ul> 555 </nav> 556 </li> 557 558 559 560 561 562 563 564 565 566 <li class="md-nav__item md-nav__item--active md-nav__item--nested"> 567 568 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-9" type="checkbox" id="nav-9" checked> 569 570 <label class="md-nav__link" for="nav-9"> 571 References 572 </label> 573 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 574 <label class="md-nav__title" for="nav-9"> 575 References 576 </label> 577 <ul class="md-nav__list" data-md-scrollfix> 578 579 580 581 582 583 584 585 586 587 <li class="md-nav__item md-nav__item--active"> 588 589 <input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc"> 590 591 592 <label class="md-nav__link md-nav__link--active" for="toc"> 593 Overview 594 </label> 595 596 <a href="./" title="Overview" class="md-nav__link md-nav__link--active"> 597 Overview 598 </a> 599 600 601 <nav class="md-nav md-nav--secondary"> 602 603 604 605 <label class="md-nav__title" for="toc">Table of contents</label> 606 <ul class="md-nav__list" data-md-scrollfix> 607 608 <li class="md-nav__item"> 609 <a href="#create-your-content-types" title="Create Your Content Types" class="md-nav__link"> 610 Create Your Content Types 611 </a> 612 613 </li> 614 615 <li class="md-nav__item"> 616 <a href="#designed-for-http2" title="Designed For HTTP/2" class="md-nav__link"> 617 Designed For HTTP/2 618 </a> 619 620 <nav class="md-nav"> 621 <ul class="md-nav__list"> 622 623 <li class="md-nav__item"> 624 <a href="#requestresponse-multiplexing" title="Request/Response Multiplexing" class="md-nav__link"> 625 Request/Response Multiplexing 626 </a> 627 628 </li> 629 630 <li class="md-nav__item"> 631 <a href="#server-push" title="Server Push" class="md-nav__link"> 632 Server Push 633 </a> 634 635 <nav class="md-nav"> 636 <ul class="md-nav__list"> 637 638 <li class="md-nav__item"> 639 <a href="#example" title="Example" class="md-nav__link"> 640 Example 641 </a> 642 643 </li> 644 645 </ul> 646 </nav> 647 648 </li> 649 650 </ul> 651 </nav> 652 653 </li> 654 655 <li class="md-nav__item"> 656 <a href="#other-considerations" title="Other Considerations" class="md-nav__link"> 657 Other Considerations 658 </a> 659 660 </li> 661 662 663 664 </ul> 665 666 </nav> 667 668 </li> 669 670 671 </ul> 672 </nav> 673 </li> 674 675 676 677 678 679 680 681 <li class="md-nav__item md-nav__item--nested"> 682 683 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-10" type="checkbox" id="nav-10"> 684 685 <label class="md-nav__link" for="nav-10"> 686 Running Backups 687 </label> 688 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 689 <label class="md-nav__title" for="nav-10"> 690 Running Backups 691 </label> 692 <ul class="md-nav__list" data-md-scrollfix> 693 694 695 696 697 698 699 700 <li class="md-nav__item"> 701 <a href="../../Running-Backups/Backups/" title="Backups" class="md-nav__link"> 702 Backups 703 </a> 704 </li> 705 706 707 </ul> 708 </nav> 709 </li> 710 711 712 713 714 715 716 717 <li class="md-nav__item md-nav__item--nested"> 718 719 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-11" type="checkbox" id="nav-11"> 720 721 <label class="md-nav__link" for="nav-11"> 722 System Configuration 723 </label> 724 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 725 <label class="md-nav__title" for="nav-11"> 726 System Configuration 727 </label> 728 <ul class="md-nav__list" data-md-scrollfix> 729 730 731 732 733 734 735 736 <li class="md-nav__item"> 737 <a href="../../System-Configuration/Settings/" title="Settings" class="md-nav__link"> 738 Settings 739 </a> 740 </li> 741 742 743 </ul> 744 </nav> 745 </li> 746 747 748 749 750 751 752 753 <li class="md-nav__item md-nav__item--nested"> 754 755 <input class="md-toggle md-nav__toggle" data-md-toggle="nav-12" type="checkbox" id="nav-12"> 756 757 <label class="md-nav__link" for="nav-12"> 758 System Deployment 759 </label> 760 <nav class="md-nav" data-md-component="collapsible" data-md-level="1"> 761 <label class="md-nav__title" for="nav-12"> 762 System Deployment 763 </label> 764 <ul class="md-nav__list" data-md-scrollfix> 765 766 767 768 769 770 771 772 <li class="md-nav__item"> 773 <a href="../../System-Deployment/Docker/" title="Docker" class="md-nav__link"> 774 Docker 775 </a> 776 </li> 777 778 779 780 781 782 783 784 <li class="md-nav__item"> 785 <a href="../../System-Deployment/SysV-Style/" title="SysV Style" class="md-nav__link"> 786 SysV Style 787 </a> 788 </li> 789 790 791 </ul> 792 </nav> 793 </li> 794 795 796 </ul> 797 </nav> 798 </div> 799 </div> 800 </div> 801 802 803 <div class="md-sidebar md-sidebar--secondary" data-md-component="toc"> 804 <div class="md-sidebar__scrollwrap"> 805 <div class="md-sidebar__inner"> 806 807 <nav class="md-nav md-nav--secondary"> 808 809 810 811 <label class="md-nav__title" for="toc">Table of contents</label> 812 <ul class="md-nav__list" data-md-scrollfix> 813 814 <li class="md-nav__item"> 815 <a href="#create-your-content-types" title="Create Your Content Types" class="md-nav__link"> 816 Create Your Content Types 817 </a> 818 819 </li> 820 821 <li class="md-nav__item"> 822 <a href="#designed-for-http2" title="Designed For HTTP/2" class="md-nav__link"> 823 Designed For HTTP/2 824 </a> 825 826 <nav class="md-nav"> 827 <ul class="md-nav__list"> 828 829 <li class="md-nav__item"> 830 <a href="#requestresponse-multiplexing" title="Request/Response Multiplexing" class="md-nav__link"> 831 Request/Response Multiplexing 832 </a> 833 834 </li> 835 836 <li class="md-nav__item"> 837 <a href="#server-push" title="Server Push" class="md-nav__link"> 838 Server Push 839 </a> 840 841 <nav class="md-nav"> 842 <ul class="md-nav__list"> 843 844 <li class="md-nav__item"> 845 <a href="#example" title="Example" class="md-nav__link"> 846 Example 847 </a> 848 849 </li> 850 851 </ul> 852 </nav> 853 854 </li> 855 856 </ul> 857 </nav> 858 859 </li> 860 861 <li class="md-nav__item"> 862 <a href="#other-considerations" title="Other Considerations" class="md-nav__link"> 863 Other Considerations 864 </a> 865 866 </li> 867 868 869 870 </ul> 871 872 </nav> 873 </div> 874 </div> 875 </div> 876 877 878 <div class="md-content"> 879 <article class="md-content__inner md-typeset"> 880 881 882 883 <h1>Overview</h1> 884 885 <p>References in Ponzu allow you to create relationships between your Content types. 886 Ponzu uses an embedded database, rather than a more traditional relational database 887 with SQL support. This may seem unnatural since there is no native concept of 888 "foreign keys" or "joins" like you may be used to. Instead, Ponzu wires up your 889 data using references, which are simply URL paths, like <code>/api/content?type=Post&id=1</code></p> 890 <p>A foreign key as a URL path?! Am I crazy? No! For the purpose Ponzu serves, 891 this structure works quite well, especially given its creation was specifically 892 tuned for HTTP/2 features such as "Request/Response Multiplexing" and "Server Push." </p> 893 <p>There is a deeper dive into the HTTP/2 concepts <a href="../../References/Overview/#designed-for-http2">below</a>, but first we'll walk through 894 a quick tutorial on Ponzu's references. </p> 895 <p>To generate references from the CLI, please <a href="../../CLI/Generating-References">read through the documentation</a>. 896 The example below assumes you understand the syntax. </p> 897 <hr /> 898 <h3 id="create-your-content-types">Create Your Content Types<a class="headerlink" href="#create-your-content-types" title="Permanent link">¶</a></h3> 899 <p>Here we are creating two Content types, <code>Author</code> and <code>Book</code>. A <code>Book</code> will keep 900 a reference to an <code>Author</code> in the sense that an author wrote the book.</p> 901 <div class="codehilite"><pre><span></span>$ ponzu gen c author name:string photo:string:file bio:string:textarea 902 $ ponzu gen c book title:string author:@author,name pages:int year:int 903 </pre></div> 904 905 906 <p>The structs generated for each look like:</p> 907 <p><code>content/author.go</code></p> 908 <div class="codehilite"><pre><span></span><span class="kd">type</span> <span class="nx">Author</span> <span class="kd">struct</span> <span class="p">{</span> 909 <span class="nx">item</span><span class="p">.</span><span class="nx">Item</span> 910 911 <span class="nx">Name</span> <span class="kt">string</span> <span class="s">`json:"name"`</span> 912 <span class="nx">Photo</span> <span class="kt">string</span> <span class="s">`json:"photo"`</span> 913 <span class="nx">Bio</span> <span class="kt">string</span> <span class="s">`json:"bio"`</span> 914 <span class="p">}</span> 915 </pre></div> 916 917 918 <p><code>content/book.go</code></p> 919 <div class="codehilite"><pre><span></span><span class="kd">type</span> <span class="nx">Book</span> <span class="kd">struct</span> <span class="p">{</span> 920 <span class="nx">item</span><span class="p">.</span><span class="nx">Item</span> 921 922 <span class="nx">Title</span> <span class="kt">string</span> <span class="s">`json:"title"`</span> 923 <span class="nx">Author</span> <span class="kt">string</span> <span class="s">`json:"author"`</span> 924 <span class="nx">Pages</span> <span class="kt">int</span> <span class="s">`json:"pages"`</span> 925 <span class="nx">Year</span> <span class="kt">int</span> <span class="s">`json:"year"`</span> 926 <span class="p">}</span> 927 </pre></div> 928 929 930 <p>Notice how the <code>Author</code> field within the <code>Book</code> struct is a <code>string</code> type, not 931 an <code>Author</code> type. This is because the <code>Author</code> is stored as a <code>string</code> in our 932 database, as a reference to the <code>Author</code>, instead of embedding the <code>Author</code> data 933 inside the <code>Book</code>. </p> 934 <p>Some example JSON data for the two structs looks like:</p> 935 <p><kbd>GET</kbd> <code>/api/content?type=Author&id=1</code> (<code>Author</code>)</p> 936 <div class="codehilite"><pre><span></span><span class="p">{</span> 937 <span class="nt">"data"</span><span class="p">:</span> <span class="p">[</span> 938 <span class="p">{</span> 939 <span class="nt">"uuid"</span><span class="p">:</span> <span class="s2">"024a5797-e064-4ee0-abe3-415cb6d3ed18"</span><span class="p">,</span> 940 <span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> 941 <span class="nt">"slug"</span><span class="p">:</span> <span class="s2">"item-id-024a5797-e064-4ee0-abe3-415cb6d3ed18"</span><span class="p">,</span> 942 <span class="nt">"timestamp"</span><span class="p">:</span> <span class="mi">1493926453826</span><span class="p">,</span> 943 <span class="nt">"updated"</span><span class="p">:</span> <span class="mi">1493926453826</span><span class="p">,</span> 944 <span class="nt">"name"</span><span class="p">:</span> <span class="s2">"Shel Silverstein"</span><span class="p">,</span> 945 <span class="nt">"photo"</span><span class="p">:</span> <span class="s2">"/api/uploads/2017/05/shel-silverstein.jpg"</span><span class="p">,</span> 946 <span class="nt">"bio"</span><span class="p">:</span> <span class="s2">"Sheldon Allan Silverstein was an American poet..."</span> 947 <span class="p">}</span> 948 <span class="p">]</span> 949 <span class="p">}</span> 950 </pre></div> 951 952 953 <p><kbd>GET</kbd> <code>/api/content?type=Book&id=1</code> (<code>Book</code>)</p> 954 <div class="codehilite"><pre><span></span><span class="p">{</span> 955 <span class="nt">"data"</span><span class="p">:</span> <span class="p">[</span> 956 <span class="p">{</span> 957 <span class="nt">"uuid"</span><span class="p">:</span> <span class="s2">"024a5797-e064-4ee0-abe3-415cb6d3ed18"</span><span class="p">,</span> 958 <span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> 959 <span class="nt">"slug"</span><span class="p">:</span> <span class="s2">"item-id-024a5797-e064-4ee0-abe3-415cb6d3ed18"</span><span class="p">,</span> 960 <span class="nt">"timestamp"</span><span class="p">:</span> <span class="mi">1493926453826</span><span class="p">,</span> 961 <span class="nt">"updated"</span><span class="p">:</span> <span class="mi">1493926453826</span><span class="p">,</span> 962 <span class="nt">"title"</span><span class="p">:</span> <span class="s2">"The Giving Tree"</span><span class="p">,</span> 963 <span class="nt">"author"</span><span class="p">:</span> <span class="s2">"/api/content?type=Author&id=1"</span><span class="p">,</span> 964 <span class="nt">"pages"</span><span class="p">:</span> <span class="mi">57</span><span class="p">,</span> 965 <span class="nt">"year"</span><span class="p">:</span> <span class="mi">1964</span> 966 <span class="p">}</span> 967 <span class="p">]</span> 968 <span class="p">}</span> 969 </pre></div> 970 971 972 <p>As you can see, the <code>Author</code> is a reference as the <code>author</code> field in the JSON 973 response for a <code>Book</code>. When you're building your client, you need to make a second 974 request for the <code>Author</code>, to the URL path found in the <code>author</code> field of the <code>Book</code> 975 response. </p> 976 <p>For example, in pseudo-code: </p> 977 <div class="codehilite"><pre><span></span><span class="c1"># Request 1: </span> 978 <span class="nv">$book</span> <span class="o">=</span> GET /api/content?type<span class="o">=</span>Book<span class="p">&</span><span class="nv">id</span><span class="o">=</span><span class="m">1</span> 979 980 <span class="c1"># Request 2: </span> 981 <span class="nv">$author</span> <span class="o">=</span> GET <span class="nv">$book</span>.author <span class="c1"># where author = /api/content?type=Author&id=1</span> 982 </pre></div> 983 984 985 <p>Until recently, this would be considered bad practice and would be costly to do 986 over HTTP. However, with the wide availability of HTTP/2 clients, including all 987 modern web browsers, mobile devices, and HTTP/2 libraries in practically every 988 programming language, this pattern is fast and scalable. </p> 989 <hr /> 990 <h3 id="designed-for-http2">Designed For HTTP/2<a class="headerlink" href="#designed-for-http2" title="Permanent link">¶</a></h3> 991 <p>At this point, you've likely noticed that you're still making two independent 992 HTTP requests to your Ponzu server. Further, if there are multiple references or more 993 than one item, you'll be making many requests -- <em>how can that be efficient?</em> </p> 994 <p>There are two main concepts at play: Request/Response Multiplexing and Server Push.</p> 995 <h4 id="requestresponse-multiplexing">Request/Response Multiplexing<a class="headerlink" href="#requestresponse-multiplexing" title="Permanent link">¶</a></h4> 996 <p>With HTTP/2, a client and server (peers) transfer data over a single TCP connection, 997 and can send data back and forth at the same time. No longer does a request need 998 to wait to be sent until after an expected response is read. This means that HTTP 999 requests can be sent much faster and at the <em>same time</em> on a single connection. 1000 Where previously, a client would open up several TCP connections, the re-use of a 1001 single connection reduces CPU overhead and makes the server more efficient.</p> 1002 <p>This feature is automatically provided to you when using HTTP/2 - the only 1003 requirement is that you connect via HTTPS and have active TLS certificates, which 1004 you can get for free by running Ponzu with the <code>--https</code> flag and configuring it 1005 with a properly set, active domain name of your own. </p> 1006 <h4 id="server-push">Server Push<a class="headerlink" href="#server-push" title="Permanent link">¶</a></h4> 1007 <p>Another impactful feature of HTTP/2 is "Server Push": the ability to preemptively 1008 send a response from the server to a client without waiting for a request. This 1009 is where Ponzu's reference design really shows it's power. Let's revisit the 1010 example from above:</p> 1011 <div class="codehilite"><pre><span></span><span class="c1"># Request 1: </span> 1012 <span class="nv">$book</span> <span class="o">=</span> GET /api/content?type<span class="o">=</span>Book<span class="p">&</span><span class="nv">id</span><span class="o">=</span><span class="m">1</span> 1013 1014 <span class="c1"># Request 2: </span> 1015 <span class="nv">$author</span> <span class="o">=</span> GET <span class="nv">$book</span>.author <span class="c1"># where author = /api/content?type=Author&id=1</span> 1016 </pre></div> 1017 1018 1019 <p>Instead of waiting for the server to respond with the data for <code>$book.author</code>, 1020 the response data is already in the client's cache before we even make the request! 1021 Now there is no round-trip made to the server and back, and the client reads the 1022 pushed response from cache in fractions of a millisecond. </p> 1023 <p>But, how does the server know which response to push and when? You'll need to 1024 specify which fields of the type you've requested should be pushed. This is done 1025 by implementing the <a href="../../Interfaces/Item#itempushable"><code>item.Pushable</code> interface</a>. 1026 See the example below which demonstrates a complete implementation on the <code>Book</code> 1027 struct, which has a reference to an <code>Author</code>.</p> 1028 <h5 id="example">Example<a class="headerlink" href="#example" title="Permanent link">¶</a></h5> 1029 <p><code>content/book.go</code></p> 1030 <div class="codehilite"><pre><span></span><span class="o">...</span> 1031 <span class="kd">type</span> <span class="nx">Book</span> <span class="kd">struct</span> <span class="p">{</span> 1032 <span class="nx">item</span><span class="p">.</span><span class="nx">Item</span> 1033 1034 <span class="nx">Title</span> <span class="kt">string</span> <span class="s">`json:"title"`</span> 1035 <span class="nx">Author</span> <span class="kt">string</span> <span class="s">`json:"author"`</span> 1036 <span class="nx">Pages</span> <span class="kt">int</span> <span class="s">`json:"pages"`</span> 1037 <span class="nx">Year</span> <span class="kt">int</span> <span class="s">`json:"year"`</span> 1038 <span class="p">}</span> 1039 1040 1041 <span class="kd">func</span> <span class="p">(</span><span class="nx">b</span> <span class="o">*</span><span class="nx">Book</span><span class="p">)</span> <span class="nx">Push</span><span class="p">(</span><span class="nx">res</span> <span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span> <span class="nx">req</span> <span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span> <span class="p">([]</span><span class="kt">string</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span> 1042 <span class="k">return</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span> 1043 <span class="c1">// the json struct tag is used to tell the server which</span> 1044 <span class="c1">// field(s) it should push - only URL paths originating</span> 1045 <span class="c1">// from your server can be pushed!</span> 1046 <span class="s">"author"</span><span class="p">,</span> 1047 <span class="p">},</span> <span class="kc">nil</span> 1048 <span class="p">}</span> 1049 <span class="o">...</span> 1050 </pre></div> 1051 1052 1053 <p>Now, whenever a single <code>Book</code> is requested, the server will preemptively push the 1054 <code>Author</code> referenced by the book. The response for the <code>Author</code> will <em>already be 1055 on the client</em> and will remain there until a request for the referenced <code>Author</code> 1056 has been made.</p> 1057 <div class="admonition note"> 1058 <p class="admonition-title">What else can I Push?</p> 1059 <p>Only fields that are URL paths originating from your server can be pushed. 1060 This means that you could also implement <code>item.Pushable</code> on the <code>Author</code> 1061 type, and return <code>[]string{"photo"}, nil</code> to push the Author's image!</p> 1062 </div> 1063 <hr /> 1064 <h3 id="other-considerations">Other Considerations<a class="headerlink" href="#other-considerations" title="Permanent link">¶</a></h3> 1065 <p>HTTP/2 Server Push is a powerful feature, but it can be abused just like anything 1066 else. To try and help mitigate potential issues, Ponzu has put some "stop-gaps" 1067 in place. Server Push is only activated on <strong>single item</strong> API responses, so you 1068 shouldn't expect to see references or files pushed from the <code>/api/contents</code> endpoint. 1069 An exception to this is the <code>/api/search</code> endpoint, which only the <strong>first</strong> 1070 result is pushed (if applicable) no matter how many items are in the response. </p> 1071 <p>You should take advantage of HTTP/2 in Ponzu and get the most out of the system. 1072 With the automatic HTTPS feature, there is no reason not to and you gain the 1073 additional benefit of encrypting your traffic - which your users will appreciate!</p> 1074 1075 1076 1077 1078 1079 1080 1081 </article> 1082 </div> 1083 </div> 1084 </main> 1085 1086 1087 <footer class="md-footer"> 1088 1089 <div class="md-footer-nav"> 1090 <nav class="md-footer-nav__inner md-grid"> 1091 1092 <a href="../../Quickstart/Overview/" title="Overview" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev"> 1093 <div class="md-flex__cell md-flex__cell--shrink"> 1094 <i class="md-icon md-icon--arrow-back md-footer-nav__button"></i> 1095 </div> 1096 <div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> 1097 <span class="md-flex__ellipsis"> 1098 <span class="md-footer-nav__direction"> 1099 Previous 1100 </span> 1101 Overview 1102 </span> 1103 </div> 1104 </a> 1105 1106 1107 <a href="../../Running-Backups/Backups/" title="Backups" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next"> 1108 <div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title"> 1109 <span class="md-flex__ellipsis"> 1110 <span class="md-footer-nav__direction"> 1111 Next 1112 </span> 1113 Backups 1114 </span> 1115 </div> 1116 <div class="md-flex__cell md-flex__cell--shrink"> 1117 <i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i> 1118 </div> 1119 </a> 1120 1121 </nav> 1122 </div> 1123 1124 <div class="md-footer-meta md-typeset"> 1125 <div class="md-footer-meta__inner md-grid"> 1126 <div class="md-footer-copyright"> 1127 1128 powered by 1129 <a href="http://www.mkdocs.org" title="MkDocs">MkDocs</a> 1130 and 1131 <a href="http://squidfunk.github.io/mkdocs-material/" title="Material for MkDocs"> 1132 Material for MkDocs</a> 1133 </div> 1134 1135 1136 <div class="md-footer-social"> 1137 1138 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> 1139 1140 <a href="https://github.com/rpdict" class="md-footer-social__link fa fa-github"></a> 1141 1142 <a href="https://twitter.com/ponzu_cms" class="md-footer-social__link fa fa-twitter"></a> 1143 1144 </div> 1145 1146 1147 </div> 1148 </div> 1149 </footer> 1150 1151 </div> 1152 1153 <script src="../../assets/javascripts/application-6b599127bc.js"></script> 1154 <script>app.initialize({url:{base:"../.."}})</script> 1155 1156 1157 1158 1159 <script>!function(e,t,a,n,o,c,i){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,c=t.createElement(a),i=t.getElementsByTagName(a)[0],c.async=1,c.src=n,i.parentNode.insertBefore(c,i)}(window,document,"script","https://www.google-analytics.com/analytics.js","ga"),ga("create","UA-98609560-1","auto"),ga("set","anonymizeIp",!0),ga("send","pageview");var links=document.getElementsByTagName("a");Array.prototype.map.call(links,function(e){e.host!=document.location.host&&e.addEventListener("click",function(){var t=e.getAttribute("data-md-action")||"follow";ga("send","event","outbound",t,e.href)})});var query=document.forms.search.query;query.addEventListener("blur",function(){if(this.value){var e=document.location.pathname;ga("send","pageview",e+"?q="+this.value)}})</script> 1160 1161 1162 </body> 1163 </html>