{
    "docs": [
        {
            "location": "/", 
            "text": "Vapor Documentation\n\n\nThis is the documentation for Vapor, a Web Framework for Swift that works on macOS and Ubuntu, and all of the packages that Vapor offers.\n\n\nVapor is the most used web framework for Swift. It provides a beautifully expressive and easy to use foundation for your next website or API.\n\n\nGetting Started\n\n\nIf this is your first time using Vapor, head to the \nInstall \n macOS\n section to install Swift and Vapor.\n\n\nOnce you have Vapor installed, check out \nGetting Started \n Hello, world\n to create your first Vapor app!\n\n\nLike Vapor?\n\n\nOur small team works hard to make Vapor awesome (and free). Support the framework by \nstarring Vapor on GitHub\n\nor \ndonating $1 monthly\nit helps us a lot. Thanks!\n\n\nOther Sources\n\n\nHere are some other great places to find information about Vapor.\n\n\n\n\n\n\n\n\nname\n\n\ndescription\n\n\nlink\n\n\n\n\n\n\n\n\n\n\nVapor Slack\n\n\nChat with ~5,000 Vapor developers.\n\n\nvisit \n\n\n\n\n\n\nAPI docs\n\n\nAuto-generated documentation from code comments.\n\n\nvisit \n\n\n\n\n\n\nStack Overflow\n\n\nAsk and answer questions with the \nvapor\n tag.\n\n\nvisit \n\n\n\n\n\n\nSource Code\n\n\nLearn how Vapor works under the hood.\n\n\nvisit \n\n\n\n\n\n\nGitHub Issues\n\n\nReport bugs or request features on GitHub.\n\n\nvisit \n\n\n\n\n\n\n\n\nService Providers\n\n\nVapor providers are a convenient way to add functionality to your Vapor projects.\nFor a full list of providers, check out the \nvapor-service\n tag on GitHub.\n\n\nAuthors\n\n\nTanner Nelson\n, \nLogan Wright\n, \nJoannis Orlandos\n, and the hundreds of members of Vapor.", 
            "title": "Overview"
        }, 
        {
            "location": "/#vapor-documentation", 
            "text": "This is the documentation for Vapor, a Web Framework for Swift that works on macOS and Ubuntu, and all of the packages that Vapor offers.  Vapor is the most used web framework for Swift. It provides a beautifully expressive and easy to use foundation for your next website or API.", 
            "title": "Vapor Documentation"
        }, 
        {
            "location": "/#getting-started", 
            "text": "If this is your first time using Vapor, head to the  Install   macOS  section to install Swift and Vapor.  Once you have Vapor installed, check out  Getting Started   Hello, world  to create your first Vapor app!", 
            "title": "Getting Started"
        }, 
        {
            "location": "/#like-vapor", 
            "text": "Our small team works hard to make Vapor awesome (and free). Support the framework by  starring Vapor on GitHub \nor  donating $1 monthly it helps us a lot. Thanks!", 
            "title": "Like Vapor?"
        }, 
        {
            "location": "/#other-sources", 
            "text": "Here are some other great places to find information about Vapor.     name  description  link      Vapor Slack  Chat with ~5,000 Vapor developers.  visit     API docs  Auto-generated documentation from code comments.  visit     Stack Overflow  Ask and answer questions with the  vapor  tag.  visit     Source Code  Learn how Vapor works under the hood.  visit     GitHub Issues  Report bugs or request features on GitHub.  visit", 
            "title": "Other Sources"
        }, 
        {
            "location": "/#service-providers", 
            "text": "Vapor providers are a convenient way to add functionality to your Vapor projects.\nFor a full list of providers, check out the  vapor-service  tag on GitHub.", 
            "title": "Service Providers"
        }, 
        {
            "location": "/#authors", 
            "text": "Tanner Nelson ,  Logan Wright ,  Joannis Orlandos , and the hundreds of members of Vapor.", 
            "title": "Authors"
        }, 
        {
            "location": "/install/macos/", 
            "text": "Install on macOS\n\n\nTo use Vapor on macOS, you just need to have Xcode 9.3 or greater installed.\n\n\nInstall Xcode\n\n\nInstall \nXcode 9.3 or greater\n from the Mac App Store.\n\n\n\n\n\n\nWarning\n\n\nAfter Xcode has been downloaded, you must open it to finish the installation. This may take a while.\n\n\n\n\nVerify Installation\n\n\nDouble check the installation was successful by opening Terminal and running:\n\n\nswift --version\n\n\n\n\n\nYou should see output similar to:\n\n\nApple Swift version \n4\n.1.0 \n(\nswiftlang-900.0.69.2 clang-900.0.38\n)\n\nTarget: x86_64-apple-macosx10.9\n\n\n\n\n\nVapor requires Swift 4.1 or greater.\n\n\nInstall Vapor\n\n\nNow that you have Swift 4.1, let's install the \nVapor Toolbox\n.\n\n\nThe toolbox includes all of Vapor's dependencies as well as a handy CLI tool for creating new projects.\n\n\nbrew install vapor/tap/vapor\n\n\n\n\n\n\n\nTip\n\n\nIf you don't already have Homebrew installed, install it at \nbrew.sh \n\n\n\n\nVerify Installation\n\n\nDouble check the installation was successful by opening Terminal and running:\n\n\nvapor --help\n\n\n\n\n\nYou should see a long list of available commands.\n\n\nDone\n\n\nNow that you have installed Vapor, create your first app in \nGetting Started \n Hello, world\n.", 
            "title": "macOS"
        }, 
        {
            "location": "/install/macos/#install-on-macos", 
            "text": "To use Vapor on macOS, you just need to have Xcode 9.3 or greater installed.", 
            "title": "Install on macOS"
        }, 
        {
            "location": "/install/macos/#install-xcode", 
            "text": "Install  Xcode 9.3 or greater  from the Mac App Store.    Warning  After Xcode has been downloaded, you must open it to finish the installation. This may take a while.", 
            "title": "Install Xcode"
        }, 
        {
            "location": "/install/macos/#verify-installation", 
            "text": "Double check the installation was successful by opening Terminal and running:  swift --version  You should see output similar to:  Apple Swift version  4 .1.0  ( swiftlang-900.0.69.2 clang-900.0.38 ) \nTarget: x86_64-apple-macosx10.9  Vapor requires Swift 4.1 or greater.", 
            "title": "Verify Installation"
        }, 
        {
            "location": "/install/macos/#install-vapor", 
            "text": "Now that you have Swift 4.1, let's install the  Vapor Toolbox .  The toolbox includes all of Vapor's dependencies as well as a handy CLI tool for creating new projects.  brew install vapor/tap/vapor   Tip  If you don't already have Homebrew installed, install it at  brew.sh", 
            "title": "Install Vapor"
        }, 
        {
            "location": "/install/macos/#verify-installation_1", 
            "text": "Double check the installation was successful by opening Terminal and running:  vapor --help  You should see a long list of available commands.", 
            "title": "Verify Installation"
        }, 
        {
            "location": "/install/macos/#done", 
            "text": "Now that you have installed Vapor, create your first app in  Getting Started   Hello, world .", 
            "title": "Done"
        }, 
        {
            "location": "/install/ubuntu/", 
            "text": "Install on Ubuntu\n\n\nInstalling Vapor on Ubuntu only takes a couple of minutes.\n\n\nSupported\n\n\nVapor supports the same versions of Ubuntu that Swift supports.\n\n\n\n\n\n\n\n\nVersion\n\n\nCodename\n\n\n\n\n\n\n\n\n\n\n16.10\n\n\nYakkety Yak\n\n\n\n\n\n\n16.04\n\n\nXenial Xerus\n\n\n\n\n\n\n14.04\n\n\nTrusty Tahr\n\n\n\n\n\n\n\n\nAPT Repo\n\n\nAdd Vapor's APT repo to get access to all of Vapor's Ubuntu packages.\n\n\nQuick Script\n\n\nEasily add Vapor's APT repo with this handy script.\n\n\neval\n \n$(\ncurl -sL https://apt.vapor.sh\n)\n\n\n\n\n\n\n\n\nTip\n\n\nThis command requires \ncurl\n which can be installed using \nsudo apt-get install curl\n\n\n\n\nDockerfile\n\n\nWhen configuring Ubuntu from a Dockerfile, adding the APT repo can be done via this command:\n\n\nRUN /bin/bash -c \n$(\nwget -qO- https://apt.vapor.sh\n)\n\n\n\n\n\n\nManual\n\n\nOr add the repo manually.\n\n\nwget -q https://repo.vapor.codes/apt/keyring.gpg -O- \n|\n sudo apt-key add -\n\necho\n \ndeb https://repo.vapor.codes/apt \n$(\nlsb_release -sc\n)\n main\n \n|\n sudo tee /etc/apt/sources.list.d/vapor.list\nsudo apt-get update\n\n\n\n\n\nInstall Vapor\n\n\nNow that you have added Vapor's APT repo, you can install the required dependencies.\n\n\nsudo apt-get install swift vapor\n\n\n\n\n\nVerify Installation\n\n\nDouble check everything worked with the following commands.\n\n\nSwift\n\n\nswift --version\n\n\n\n\n\nYou should see output similar to:\n\n\nApple Swift version \n4\n.1.0 \n(\nswiftlang-900.0.69.2 clang-900.0.38\n)\n\nTarget: x86_64-apple-macosx10.9\n\n\n\n\n\nVapor requires Swift 4.1 or greater.\n\n\nVapor Toolbox\n\n\nvapor --help\n\n\n\n\n\nYou should see a long list of available commands.\n\n\nDone\n\n\nNow that you have installed Vapor, create your first app in \nGetting Started \n Hello, world\n.\n\n\nSwift.org\n\n\nCheck out \nSwift.org\n's guide to \nusing downloads\n if you need more detailed instructions for installing Swift 4.1.", 
            "title": "Ubuntu"
        }, 
        {
            "location": "/install/ubuntu/#install-on-ubuntu", 
            "text": "Installing Vapor on Ubuntu only takes a couple of minutes.", 
            "title": "Install on Ubuntu"
        }, 
        {
            "location": "/install/ubuntu/#supported", 
            "text": "Vapor supports the same versions of Ubuntu that Swift supports.     Version  Codename      16.10  Yakkety Yak    16.04  Xenial Xerus    14.04  Trusty Tahr", 
            "title": "Supported"
        }, 
        {
            "location": "/install/ubuntu/#apt-repo", 
            "text": "Add Vapor's APT repo to get access to all of Vapor's Ubuntu packages.", 
            "title": "APT Repo"
        }, 
        {
            "location": "/install/ubuntu/#quick-script", 
            "text": "Easily add Vapor's APT repo with this handy script.  eval   $( curl -sL https://apt.vapor.sh )    Tip  This command requires  curl  which can be installed using  sudo apt-get install curl", 
            "title": "Quick Script"
        }, 
        {
            "location": "/install/ubuntu/#dockerfile", 
            "text": "When configuring Ubuntu from a Dockerfile, adding the APT repo can be done via this command:  RUN /bin/bash -c  $( wget -qO- https://apt.vapor.sh )", 
            "title": "Dockerfile"
        }, 
        {
            "location": "/install/ubuntu/#manual", 
            "text": "Or add the repo manually.  wget -q https://repo.vapor.codes/apt/keyring.gpg -O-  |  sudo apt-key add - echo   deb https://repo.vapor.codes/apt  $( lsb_release -sc )  main   |  sudo tee /etc/apt/sources.list.d/vapor.list\nsudo apt-get update", 
            "title": "Manual"
        }, 
        {
            "location": "/install/ubuntu/#install-vapor", 
            "text": "Now that you have added Vapor's APT repo, you can install the required dependencies.  sudo apt-get install swift vapor", 
            "title": "Install Vapor"
        }, 
        {
            "location": "/install/ubuntu/#verify-installation", 
            "text": "Double check everything worked with the following commands.", 
            "title": "Verify Installation"
        }, 
        {
            "location": "/install/ubuntu/#swift", 
            "text": "swift --version  You should see output similar to:  Apple Swift version  4 .1.0  ( swiftlang-900.0.69.2 clang-900.0.38 ) \nTarget: x86_64-apple-macosx10.9  Vapor requires Swift 4.1 or greater.", 
            "title": "Swift"
        }, 
        {
            "location": "/install/ubuntu/#vapor-toolbox", 
            "text": "vapor --help  You should see a long list of available commands.", 
            "title": "Vapor Toolbox"
        }, 
        {
            "location": "/install/ubuntu/#done", 
            "text": "Now that you have installed Vapor, create your first app in  Getting Started   Hello, world .", 
            "title": "Done"
        }, 
        {
            "location": "/install/ubuntu/#swiftorg", 
            "text": "Check out  Swift.org 's guide to  using downloads  if you need more detailed instructions for installing Swift 4.1.", 
            "title": "Swift.org"
        }, 
        {
            "location": "/getting-started/hello-world/", 
            "text": "Hello, world\n\n\nNow that you've installed Vapor, let's create your first Vapor app!\nThis guide will take you step by step through creating a new project, building, and running it.\n\n\nNew Project\n\n\nThe first step is to create a new Vapor project on your computer.\nFor this guide, we will call the project \nHello\n.\n\n\nOpen up your terminal, and use \nVapor Toolbox's \nnew\n command.\n\n\nvapor new Hello\n\n\n\n\n\nOnce that finishes, change into the newly created directory.\n\n\ncd\n Hello\n\n\n\n\n\nGenerate Xcode Project\n\n\nLet's now use the \nVapor Toolbox's \nxcode\n command to generate an Xcode project.\nThis will allow us to build and run our app from inside of Xcode, just like an iOS app.\n\n\nvapor xcode\n\n\n\n\n\nThe toolbox will ask you if you'd like to open Xcode automatically, select \nyes\n.\n\n\nBuild \n Run\n\n\nYou should now have Xcode open and running. Select the \nrun scheme\n from the scheme menu,\nthen click the play button.\n\n\nYou should see the terminal pop up at the bottom of the screen.\n\n\nServer starting on http://localhost:8080\n\n\n\n\n\nVisit Localhost\n\n\nOpen your web browser, and visit \nlocalhost:8080/hello \n\n\nYou should see the following page.\n\n\nHello, world!\n\n\n\n\n\nCongratulations on creating, building, and running your first Vapor app! \ud83c\udf89", 
            "title": "Hello, world"
        }, 
        {
            "location": "/getting-started/hello-world/#hello-world", 
            "text": "Now that you've installed Vapor, let's create your first Vapor app!\nThis guide will take you step by step through creating a new project, building, and running it.", 
            "title": "Hello, world"
        }, 
        {
            "location": "/getting-started/hello-world/#new-project", 
            "text": "The first step is to create a new Vapor project on your computer.\nFor this guide, we will call the project  Hello .  Open up your terminal, and use  Vapor Toolbox's  new  command.  vapor new Hello  Once that finishes, change into the newly created directory.  cd  Hello", 
            "title": "New Project"
        }, 
        {
            "location": "/getting-started/hello-world/#generate-xcode-project", 
            "text": "Let's now use the  Vapor Toolbox's  xcode  command to generate an Xcode project.\nThis will allow us to build and run our app from inside of Xcode, just like an iOS app.  vapor xcode  The toolbox will ask you if you'd like to open Xcode automatically, select  yes .", 
            "title": "Generate Xcode Project"
        }, 
        {
            "location": "/getting-started/hello-world/#build-run", 
            "text": "You should now have Xcode open and running. Select the  run scheme  from the scheme menu,\nthen click the play button.  You should see the terminal pop up at the bottom of the screen.  Server starting on http://localhost:8080", 
            "title": "Build &amp; Run"
        }, 
        {
            "location": "/getting-started/hello-world/#visit-localhost", 
            "text": "Open your web browser, and visit  localhost:8080/hello   You should see the following page.  Hello, world!  Congratulations on creating, building, and running your first Vapor app! \ud83c\udf89", 
            "title": "Visit Localhost"
        }, 
        {
            "location": "/getting-started/toolbox/", 
            "text": "Install Toolbox\n\n\nVapor's command line interface provides shortcuts and assistance for common tasks.\n\n\n\n\nHelp prints useful information about available commands and flags.\n\n\nvapor --help\n\n\n\n\n\nYou can also run the \n--help\n option on any Toolbox command.\n\n\nvapor new --help\n\n\n\n\n\nThe \n--help\n flag should be your goto for learning about the toolbox as it is the most up-to-date.\n\n\nNew\n\n\nThe Toolbox's most important feature is helping you create a new project.\n\n\nvapor new \nname\n\n\n\n\n\n\nJust pass the name of your project as the first argument to the \nnew\n command.\n\n\n\n\nNote\n\n\nProject names should be \nPascalCase \n, like \nHelloWorld\n or \nMyProject\n.\n\n\n\n\nTemplates\n\n\nBy default, Vapor will create your new project from the API template. You can choose\na different template by passing the \n--template\n flag.\n\n\n\n\n\n\n\n\nName\n\n\nFlag\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nAPI\n\n\n--template=api\n\n\nJSON API with Fluent database.\n\n\n\n\n\n\nWeb\n\n\n--template=web\n\n\nHTML website with Leaf templates.\n\n\n\n\n\n\n\n\n\n\nInfo\n\n\nThere are lots of unofficial Vapor templates on GitHub under the \nvapor\n + \ntemplate\n topcs \n.\nYou can use these by passing the full GitHub URL to the \n--template\n option.\n\n\n\n\nBuild \n Run\n\n\nYou can use the toolbox to build and run your Vapor app.\n\n\nvapor build\nvapor run\n\n\n\n\n\n\n\nTip\n\n\nWe recommend building and running through \nXcode\n if you have a Mac. \nIt's a bit faster and you can set breakpoints! \nJust use \nvapor xcode\n to generate an Xcode project.\n\n\n\n\nUpdating\n\n\nThe toolbox should be updated by the package manager it was installed with.\n\n\nHomebrew\n\n\nbrew upgrade vapor\n\n\n\n\n\nAPT\n\n\nsudo apt-get update\nsudo apt-get install vapor", 
            "title": "Toolbox"
        }, 
        {
            "location": "/getting-started/toolbox/#install-toolbox", 
            "text": "Vapor's command line interface provides shortcuts and assistance for common tasks.   Help prints useful information about available commands and flags.  vapor --help  You can also run the  --help  option on any Toolbox command.  vapor new --help  The  --help  flag should be your goto for learning about the toolbox as it is the most up-to-date.", 
            "title": "Install Toolbox"
        }, 
        {
            "location": "/getting-started/toolbox/#new", 
            "text": "The Toolbox's most important feature is helping you create a new project.  vapor new  name   Just pass the name of your project as the first argument to the  new  command.   Note  Project names should be  PascalCase  , like  HelloWorld  or  MyProject .", 
            "title": "New"
        }, 
        {
            "location": "/getting-started/toolbox/#templates", 
            "text": "By default, Vapor will create your new project from the API template. You can choose\na different template by passing the  --template  flag.     Name  Flag  Description      API  --template=api  JSON API with Fluent database.    Web  --template=web  HTML website with Leaf templates.      Info  There are lots of unofficial Vapor templates on GitHub under the  vapor  +  template  topcs  .\nYou can use these by passing the full GitHub URL to the  --template  option.", 
            "title": "Templates"
        }, 
        {
            "location": "/getting-started/toolbox/#build-run", 
            "text": "You can use the toolbox to build and run your Vapor app.  vapor build\nvapor run   Tip  We recommend building and running through  Xcode  if you have a Mac. \nIt's a bit faster and you can set breakpoints! \nJust use  vapor xcode  to generate an Xcode project.", 
            "title": "Build &amp; Run"
        }, 
        {
            "location": "/getting-started/toolbox/#updating", 
            "text": "The toolbox should be updated by the package manager it was installed with.", 
            "title": "Updating"
        }, 
        {
            "location": "/getting-started/toolbox/#homebrew", 
            "text": "brew upgrade vapor", 
            "title": "Homebrew"
        }, 
        {
            "location": "/getting-started/toolbox/#apt", 
            "text": "sudo apt-get update\nsudo apt-get install vapor", 
            "title": "APT"
        }, 
        {
            "location": "/getting-started/spm/", 
            "text": "Managing your project\n\n\nThe Swift Package Manager (SPM for short) is used for building your project's source code and dependencies. \nIt's a similar idea to Cocoapods, Ruby gems, and NPM. Most of the time the \nVapor Toolbox\n will \ninteract with SPM on your behalf. However, it's important to understand the basics.\n\n\n\n\nTip\n\n\nLearn more about SPM on \nSwift.org \n \n\n\n\n\nPackage Manifest\n\n\nThe first place SPM looks in your project is the package manfiest. This should always be located in the root\ndirectory of your project and named \nPackage.swift\n.\n\n\nDependencies\n\n\nDependencies are other SPM packages that your package relies on. All Vapor applications rely on the Vapor package,\nbut you can add as many other dependencies as you want.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nVaporApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n// \ud83d\udca7 A server-side Swift web framework. \n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/vapor.git\n,\n \nfrom\n:\n \n3.0.0-rc\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n \n...\n \n]\n\n\n)\n\n\n\n\n\n\nIn the above example, you can see \nvapor/vapor \n version 3.0\nor later is a dependency of this package.\nWhen you add a dependency to your package, you must next signal which \ntargets\n depend on\nthe newly available modules.\n\n\n\n\nWarning\n\n\nAnytime you modify the package manifest, call \nvapor update\n to effect the changes.\n\n\n\n\nTargets\n\n\nTargets are all of the modules, executables, and tests that your package contains. \n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nVaporApp\n,\n\n    \ndependencies\n:\n \n[\n \n...\n \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nVapor\n]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nMost Vapor apps will have three targets, although you can add as many as you like to organize your code.\nEach target declares which modules it depends on. You must add module names here in order to \nimport\n them in your code.\nA target can depend on other targets in your project or any modules exposed by packages you've added to\nthe \nmain dependencies\n array.\n\n\n\n\nTip\n\n\nExecutable targets (targets that contain a \nmain.swift\n file) cannot be imported by other modules.\nThis is why Vapor has both an \nApp\n and a \nRun\n target.\nAny code you include in \nApp\n can be tested in the \nAppTests\n.\n\n\n\n\nFolder Structure\n\n\nBelow is the typical folder structure for an SPM package.\n\n\n.\n\u251c\u2500\u2500 Sources\n\u2502   \u251c\u2500\u2500 App\n\u2502   \u2502   \u2514\u2500\u2500 (Source code)\n\u2502   \u2514\u2500\u2500 Run\n\u2502       \u2514\u2500\u2500 main.swift\n\u251c\u2500\u2500 Tests\n\u2502   \u2514\u2500\u2500 AppTests\n\u2514\u2500\u2500 Package.swift\n\n\n\n\n\nEach \n.target\n corresponds to a folder in the \nSources\n folder. \nEach \n.testTarget\n corresponds to a folder in the \nTests\n folder.\n\n\nTroubleshooting\n\n\nIf you are experiencing problems with SPM, sometimes cleaning your project can help.\n\n\nvapor clean", 
            "title": "SPM"
        }, 
        {
            "location": "/getting-started/spm/#managing-your-project", 
            "text": "The Swift Package Manager (SPM for short) is used for building your project's source code and dependencies. \nIt's a similar idea to Cocoapods, Ruby gems, and NPM. Most of the time the  Vapor Toolbox  will \ninteract with SPM on your behalf. However, it's important to understand the basics.   Tip  Learn more about SPM on  Swift.org", 
            "title": "Managing your project"
        }, 
        {
            "location": "/getting-started/spm/#package-manifest", 
            "text": "The first place SPM looks in your project is the package manfiest. This should always be located in the root\ndirectory of your project and named  Package.swift .", 
            "title": "Package Manifest"
        }, 
        {
            "location": "/getting-started/spm/#dependencies", 
            "text": "Dependencies are other SPM packages that your package relies on. All Vapor applications rely on the Vapor package,\nbut you can add as many other dependencies as you want.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   VaporApp , \n     dependencies :   [ \n         // \ud83d\udca7 A server-side Swift web framework.  \n         . package ( url :   https://github.com/vapor/vapor.git ,   from :   3.0.0-rc ), \n     ], \n     targets :   [   ...   ]  )   In the above example, you can see  vapor/vapor   version 3.0\nor later is a dependency of this package.\nWhen you add a dependency to your package, you must next signal which  targets  depend on\nthe newly available modules.   Warning  Anytime you modify the package manifest, call  vapor update  to effect the changes.", 
            "title": "Dependencies"
        }, 
        {
            "location": "/getting-started/spm/#targets", 
            "text": "Targets are all of the modules, executables, and tests that your package contains.   // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   VaporApp , \n     dependencies :   [   ...   ], \n     targets :   [ \n         . target ( name :   App ,   dependencies :   [ Vapor ]), \n         . target ( name :   Run ,   dependencies :   [ App ]), \n         . testTarget ( name :   AppTests ,   dependencies :   [ App ]), \n     ]  )   Most Vapor apps will have three targets, although you can add as many as you like to organize your code.\nEach target declares which modules it depends on. You must add module names here in order to  import  them in your code.\nA target can depend on other targets in your project or any modules exposed by packages you've added to\nthe  main dependencies  array.   Tip  Executable targets (targets that contain a  main.swift  file) cannot be imported by other modules.\nThis is why Vapor has both an  App  and a  Run  target.\nAny code you include in  App  can be tested in the  AppTests .", 
            "title": "Targets"
        }, 
        {
            "location": "/getting-started/spm/#folder-structure", 
            "text": "Below is the typical folder structure for an SPM package.  .\n\u251c\u2500\u2500 Sources\n\u2502   \u251c\u2500\u2500 App\n\u2502   \u2502   \u2514\u2500\u2500 (Source code)\n\u2502   \u2514\u2500\u2500 Run\n\u2502       \u2514\u2500\u2500 main.swift\n\u251c\u2500\u2500 Tests\n\u2502   \u2514\u2500\u2500 AppTests\n\u2514\u2500\u2500 Package.swift  Each  .target  corresponds to a folder in the  Sources  folder. \nEach  .testTarget  corresponds to a folder in the  Tests  folder.", 
            "title": "Folder Structure"
        }, 
        {
            "location": "/getting-started/spm/#troubleshooting", 
            "text": "If you are experiencing problems with SPM, sometimes cleaning your project can help.  vapor clean", 
            "title": "Troubleshooting"
        }, 
        {
            "location": "/getting-started/xcode/", 
            "text": "Xcode\n\n\nIf you're on a Mac, you can develop your Vapor project using Xcode. \nYou can build, run, and stop your server from within Xcode, as well as use breakpoints and instruments to debug your code.\n\n\n\n\nXcode is a great way to develop Vapor apps, but you can use any text editor you like.\n\n\nGenerate Project\n\n\nTo use Xcode, you just need to generate an Xcode project using \nVapor Toolbox\n.\n\n\nvapor xcode\n\n\n\n\n\n\n\nTip\n\n\nDon't worry about comitting the generated Xcode Project to git, just generate a new\none whenever you need it.\n\n\n\n\nRun\n\n\nTo build and run your Vapor app, first make sure you have the \nRun\n scheme selected from the schemes menu.\nAlso make sure to select \"My Mac\" as the device.\n\n\n\n\nOnce that's selected, just click the play button or press \nCommand + R\n on your keyboard.\n\n\nTest\n\n\nTo run your unit tests, select the scheme ending in \n-Package\n and press \nCommand + U\n.\n\n\n\n\nWarning\n\n\nThere may be a few extraneous schemes in the dropdown menu. Ignore them!", 
            "title": "Xcode"
        }, 
        {
            "location": "/getting-started/xcode/#xcode", 
            "text": "If you're on a Mac, you can develop your Vapor project using Xcode. \nYou can build, run, and stop your server from within Xcode, as well as use breakpoints and instruments to debug your code.   Xcode is a great way to develop Vapor apps, but you can use any text editor you like.", 
            "title": "Xcode"
        }, 
        {
            "location": "/getting-started/xcode/#generate-project", 
            "text": "To use Xcode, you just need to generate an Xcode project using  Vapor Toolbox .  vapor xcode   Tip  Don't worry about comitting the generated Xcode Project to git, just generate a new\none whenever you need it.", 
            "title": "Generate Project"
        }, 
        {
            "location": "/getting-started/xcode/#run", 
            "text": "To build and run your Vapor app, first make sure you have the  Run  scheme selected from the schemes menu.\nAlso make sure to select \"My Mac\" as the device.   Once that's selected, just click the play button or press  Command + R  on your keyboard.", 
            "title": "Run"
        }, 
        {
            "location": "/getting-started/xcode/#test", 
            "text": "To run your unit tests, select the scheme ending in  -Package  and press  Command + U .   Warning  There may be a few extraneous schemes in the dropdown menu. Ignore them!", 
            "title": "Test"
        }, 
        {
            "location": "/getting-started/structure/", 
            "text": "Structure\n\n\nThis section explains the structure of a typical Vapor application to help get\nyou familiar with where things go.\n\n\nFolder Structure\n\n\nVapor's folder structure builds on top of \nSPM's folder structure\n.\n\n\n.\n\u251c\u2500\u2500 Public\n\u251c\u2500\u2500 Sources\n\u2502   \u251c\u2500\u2500 App\n\u2502   \u2502   \u251c\u2500\u2500 Controllers\n\u2502   \u2502   \u251c\u2500\u2500 Models\n\u2502   \u2502   \u251c\u2500\u2500 boot.swift\n\u2502   \u2502   \u251c\u2500\u2500 configure.swift\n\u2502   \u2502   \u2514\u2500\u2500 routes.swift\n\u2502   \u2514\u2500\u2500 Run\n\u2502       \u2514\u2500\u2500 main.swift\n\u251c\u2500\u2500 Tests\n\u2502   \u2514\u2500\u2500 AppTests\n\u2514\u2500\u2500 Package.swift\n\n\n\n\n\nLet's take a look at what each of these folders and files does.\n\n\nPublic\n\n\nThis folder contains any public files that will be served by your app.\nThis is usually images, style sheets, and browser scripts.\n\n\nWhenever Vapor responds to a request, it will first check if the requested\nitem is in this folder. If it is, it skips your application logic and returns\nthe file immediately.\n\n\nFor example, a request to \nlocalhost:8080/favicon.ico\n will check to see\nif \nPublic/favicon.ico\n exists. If it does, Vapor will return it.\n\n\nSources\n\n\nThis folder contains all of the Swift source files for your project. \nThe top level folders (\nApp\n and \nRun\n) reflect your package's modules, \nas declared in the \npackage manifest\n.\n\n\nApp\n\n\nThis is the most important folder in your application, it's where all of\nthe application logic goes!\n\n\nControllers\n\n\nControllers are great way of grouping together application logic. Most controllers\nhave many functions that accept a request and return some sort of response.\n\n\n\n\nTip\n\n\nVapor supports, but does not enforce the MVC pattern\n\n\n\n\nModels\n\n\nThe \nModels\n folder is a great place to store your \nContent\n structs or\nFluent \nModel\ns.\n\n\nboot.swift\n\n\nThis file contains a function that will be called \nafter\n your application has booted,\nbut \nbefore\n it has started running. This is a great place do things that should happen \nevery time your application starts.\n\n\nYou have access to the \nApplication\n here which you can use to create\nany \nservices\n you might need.\n\n\nconfigure.swift\n\n\nThis file contains a function that receives the config, environment, and services for your\napplication as input. This is a great place to make changes to your config or register \n\nservices\n to your application.\n\n\nroutes.swift\n\n\nThis file contains a function for adding routes to your router.\n\n\nYou will notice there's one example route in there that returns the \"hello, world\" response we saw earlier.\n\n\nYou can create as many methods as you want to further organize your code. Just make sure to call them in this main route collection. \n\n\nTests\n\n\nEach non-executable module in your \nSources\n folder should have a corresponding \n...Tests\n folder.\n\n\nAppTests\n\n\nThis folder contains the unit tests for code in your \nApp\n module. \nLearn more about testing in \nTesting \n Getting Started\n.\n\n\nPackage.swift\n\n\nFinally is SPM's \npackage manifest\n.", 
            "title": "Folder Structure"
        }, 
        {
            "location": "/getting-started/structure/#structure", 
            "text": "This section explains the structure of a typical Vapor application to help get\nyou familiar with where things go.", 
            "title": "Structure"
        }, 
        {
            "location": "/getting-started/structure/#folder-structure", 
            "text": "Vapor's folder structure builds on top of  SPM's folder structure .  .\n\u251c\u2500\u2500 Public\n\u251c\u2500\u2500 Sources\n\u2502   \u251c\u2500\u2500 App\n\u2502   \u2502   \u251c\u2500\u2500 Controllers\n\u2502   \u2502   \u251c\u2500\u2500 Models\n\u2502   \u2502   \u251c\u2500\u2500 boot.swift\n\u2502   \u2502   \u251c\u2500\u2500 configure.swift\n\u2502   \u2502   \u2514\u2500\u2500 routes.swift\n\u2502   \u2514\u2500\u2500 Run\n\u2502       \u2514\u2500\u2500 main.swift\n\u251c\u2500\u2500 Tests\n\u2502   \u2514\u2500\u2500 AppTests\n\u2514\u2500\u2500 Package.swift  Let's take a look at what each of these folders and files does.", 
            "title": "Folder Structure"
        }, 
        {
            "location": "/getting-started/structure/#public", 
            "text": "This folder contains any public files that will be served by your app.\nThis is usually images, style sheets, and browser scripts.  Whenever Vapor responds to a request, it will first check if the requested\nitem is in this folder. If it is, it skips your application logic and returns\nthe file immediately.  For example, a request to  localhost:8080/favicon.ico  will check to see\nif  Public/favicon.ico  exists. If it does, Vapor will return it.", 
            "title": "Public"
        }, 
        {
            "location": "/getting-started/structure/#sources", 
            "text": "This folder contains all of the Swift source files for your project. \nThe top level folders ( App  and  Run ) reflect your package's modules, \nas declared in the  package manifest .", 
            "title": "Sources"
        }, 
        {
            "location": "/getting-started/structure/#app", 
            "text": "This is the most important folder in your application, it's where all of\nthe application logic goes!", 
            "title": "App"
        }, 
        {
            "location": "/getting-started/structure/#controllers", 
            "text": "Controllers are great way of grouping together application logic. Most controllers\nhave many functions that accept a request and return some sort of response.   Tip  Vapor supports, but does not enforce the MVC pattern", 
            "title": "Controllers"
        }, 
        {
            "location": "/getting-started/structure/#models", 
            "text": "The  Models  folder is a great place to store your  Content  structs or\nFluent  Model s.", 
            "title": "Models"
        }, 
        {
            "location": "/getting-started/structure/#bootswift", 
            "text": "This file contains a function that will be called  after  your application has booted,\nbut  before  it has started running. This is a great place do things that should happen \nevery time your application starts.  You have access to the  Application  here which you can use to create\nany  services  you might need.", 
            "title": "boot.swift"
        }, 
        {
            "location": "/getting-started/structure/#configureswift", 
            "text": "This file contains a function that receives the config, environment, and services for your\napplication as input. This is a great place to make changes to your config or register  services  to your application.", 
            "title": "configure.swift"
        }, 
        {
            "location": "/getting-started/structure/#routesswift", 
            "text": "This file contains a function for adding routes to your router.  You will notice there's one example route in there that returns the \"hello, world\" response we saw earlier.  You can create as many methods as you want to further organize your code. Just make sure to call them in this main route collection.", 
            "title": "routes.swift"
        }, 
        {
            "location": "/getting-started/structure/#tests", 
            "text": "Each non-executable module in your  Sources  folder should have a corresponding  ...Tests  folder.", 
            "title": "Tests"
        }, 
        {
            "location": "/getting-started/structure/#apptests", 
            "text": "This folder contains the unit tests for code in your  App  module. \nLearn more about testing in  Testing   Getting Started .", 
            "title": "AppTests"
        }, 
        {
            "location": "/getting-started/structure/#packageswift", 
            "text": "Finally is SPM's  package manifest .", 
            "title": "Package.swift"
        }, 
        {
            "location": "/getting-started/application/", 
            "text": "Application\n\n\nEvery Vapor project has an \nApplication\n. You use the application to run your server and create any services you might need at boot time.\n\n\nThe best place to access the application is in your project's \nboot.swift\n file.\n\n\nimport\n \nVapor\n\n\n\npublic\n \nfunc\n \nboot\n(\n_\n \napp\n:\n \nApplication\n)\n \nthrows\n \n{\n\n    \n// your code here\n\n\n}\n\n\n\n\n\n\nUnlike some other web frameworks, Vapor doesn't support statically accessing the application. If you need to access it from another class or struct, you should pass through a method or initializer.\n\n\n\n\nInfo\n\n\nAvoiding static access to variables helps make Vapor performant by preventing the need for thread-safe locks or semaphores.\n\n\n\n\nServices\n\n\nThe application's main function is to boot your server. \n\n\ntry\n \napp\n.\nrun\n()\n\n\n\n\n\n\nHowever, the application is also a container. You may use it to create services required to boot your application.\n\n\n\n\nWarning\n\n\nDo not use the application, or any services created from it, inside a route closure. Use the \nRequest\n to create services instead.\n\n\n\n\nlet\n \nclient\n \n=\n \ntry\n \napp\n.\nmake\n(\nClient\n.\nself\n)\n\n\nlet\n \nres\n \n=\n \ntry\n \nclient\n.\nget\n(\nhttp://vapor.codes\n).\nwait\n()\n\n\nprint\n(\nres\n)\n \n// Response\n\n\n\n\n\n\n\n\nTip\n\n\nIt's okay to use \n.wait()\n here instead of \n.map\n/\n.flatMap\n because we are not inside of a route closure.\n\n\n\n\nLearn more about services in \nGetting Started \n Services\n.", 
            "title": "Application"
        }, 
        {
            "location": "/getting-started/application/#application", 
            "text": "Every Vapor project has an  Application . You use the application to run your server and create any services you might need at boot time.  The best place to access the application is in your project's  boot.swift  file.  import   Vapor  public   func   boot ( _   app :   Application )   throws   { \n     // your code here  }   Unlike some other web frameworks, Vapor doesn't support statically accessing the application. If you need to access it from another class or struct, you should pass through a method or initializer.   Info  Avoiding static access to variables helps make Vapor performant by preventing the need for thread-safe locks or semaphores.", 
            "title": "Application"
        }, 
        {
            "location": "/getting-started/application/#services", 
            "text": "The application's main function is to boot your server.   try   app . run ()   However, the application is also a container. You may use it to create services required to boot your application.   Warning  Do not use the application, or any services created from it, inside a route closure. Use the  Request  to create services instead.   let   client   =   try   app . make ( Client . self )  let   res   =   try   client . get ( http://vapor.codes ). wait ()  print ( res )   // Response    Tip  It's okay to use  .wait()  here instead of  .map / .flatMap  because we are not inside of a route closure.   Learn more about services in  Getting Started   Services .", 
            "title": "Services"
        }, 
        {
            "location": "/getting-started/controllers/", 
            "text": "Controllers\n\n\nControllers are a great way to organize your code. They are collections of methods that accept a request and return a response.\n\n\nA good place to put your controllers is in the \nControllers\n folder.\n\n\nMethods\n\n\nLet's take a look at an example controller.\n\n\nimport\n \nVapor\n\n\n\nfinal\n \nclass\n \nHelloController\n \n{\n\n    \nfunc\n \ngreet\n(\n_\n \nreq\n:\n \nRequest\n)\n \nthrows\n \n-\n \nString\n \n{\n\n        \nreturn\n \nHello!\n\n    \n}\n\n\n}\n\n\n\n\n\n\nController methods should always accept a \nRequest\n and return something \nResponseEncodable\n. \n\n\n\n\nNote\n\n\nFutures\n whose expectations are \nResponseEncodable\n (i.e, \nFuture\nString\n) are also \nResponseEncodable\n.\n\n\n\n\nTo use this controller, we can simply initialize it, then pass the method to a router.\n\n\nlet\n \nhelloController\n \n=\n \nHelloController\n()\n\n\nrouter\n.\nget\n(\ngreet\n,\n \nuse\n:\n \nhelloController\n.\ngreet\n)\n\n\n\n\n\n\nUsing Services\n\n\nYou will probably want to access your \nservices\n from within your controllers. Just use the \nRequest\n as a container to create services from within your route closures. Vapor will take care of caching the services.\n\n\nfinal\n \nclass\n \nHelloController\n \n{\n\n    \nfunc\n \ngreet\n(\n_\n \nreq\n:\n \nRequest\n)\n \nthrows\n \n-\n \nString\n \n{\n\n        \nreturn\n \ntry\n \nreq\n.\nmake\n(\nBCryptHasher\n.\nself\n).\nhash\n(\nhello\n)\n\n    \n}\n\n\n}", 
            "title": "Controllers"
        }, 
        {
            "location": "/getting-started/controllers/#controllers", 
            "text": "Controllers are a great way to organize your code. They are collections of methods that accept a request and return a response.  A good place to put your controllers is in the  Controllers  folder.", 
            "title": "Controllers"
        }, 
        {
            "location": "/getting-started/controllers/#methods", 
            "text": "Let's take a look at an example controller.  import   Vapor  final   class   HelloController   { \n     func   greet ( _   req :   Request )   throws   -   String   { \n         return   Hello! \n     }  }   Controller methods should always accept a  Request  and return something  ResponseEncodable .    Note  Futures  whose expectations are  ResponseEncodable  (i.e,  Future String ) are also  ResponseEncodable .   To use this controller, we can simply initialize it, then pass the method to a router.  let   helloController   =   HelloController ()  router . get ( greet ,   use :   helloController . greet )", 
            "title": "Methods"
        }, 
        {
            "location": "/getting-started/controllers/#using-services", 
            "text": "You will probably want to access your  services  from within your controllers. Just use the  Request  as a container to create services from within your route closures. Vapor will take care of caching the services.  final   class   HelloController   { \n     func   greet ( _   req :   Request )   throws   -   String   { \n         return   try   req . make ( BCryptHasher . self ). hash ( hello ) \n     }  }", 
            "title": "Using Services"
        }, 
        {
            "location": "/getting-started/routing/", 
            "text": "Routing\n\n\nRouting is the process of finding the appropriate response to an incoming request.\n\n\nMaking a Router\n\n\nIn Vapor the default Router is the \nEngineRouter\n. You can implement custom routers by implementing one conforming to the \nRouter\n protocol.\n\n\nlet\n \nrouter\n \n=\n \ntry\n \nEngineRouter\n.\ndefault\n()\n\n\n\n\n\n\nThis is usually done in your \nconfigure.swift\n file.\n\n\nRegistering a route\n\n\nImagine you want to return a list of users when someone visits \nGET /users\n. Leaving authorization aside, that would look something like this.\n\n\nrouter\n.\nget\n(\nusers\n)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \n// fetch the users\n\n\n}\n\n\n\n\n\n\nIn Vapor, routing is usually done using the \n.get\n, \n.put\n, \n.post\n, \n.patch\n and \n.delete\n shorthands. You can supply the path as \n/\n or comma-separated strings. We recommend comma separated, as it's more readable.\n\n\nrouter\n.\nget\n(\npath\n,\n \nto\n,\n \nsomething\n)\n \n{\n \n...\n \n}\n\n\n\n\n\n\nRoutes\n\n\nThe best place to add routes is in the \nroutes.swift\n file. Use the router supplied as a parameter to this function to register your routes.\n\n\nimport\n \nVapor\n\n\n\npublic\n \nfunc\n \nroutes\n(\n_\n \nrouter\n:\n \nRouter\n)\n \nthrows\n \n{\n\n    \n// Basic \nHello, world!\n example\n\n    \nrouter\n.\nget\n(\nhello\n)\n \n{\n \nreq\n \nin\n\n        \nreturn\n \nHello, world!\n\n    \n}\n\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nSee \nGetting Started \n Content\n for more information about what can be returned in a route closure.\n\n\nParameters\n\n\nSometimes you may want one of the components of your route path to be dynamic. This is often used when\nyou want to get an item with a supplied identifier, e.g., \nGET /users/:id\n\n\nrouter\n.\nget\n(\nusers\n,\n \nInt\n.\nparameter\n)\n \n{\n \nreq\n \n-\n \nString\n \nin\n\n    \nlet\n \nid\n \n=\n \ntry\n \nreq\n.\nparameter\n(\nInt\n.\nself\n)\n\n    \nreturn\n \nrequested id #\n\\(\nid\n)\n\n\n}\n\n\n\n\n\n\nInstead of passing a string, pass the \ntype\n of parameter you expect. In this case, our \nUser\n has an \nInt\n ID.\n\n\n\n\nTip\n\n\nYou can define your own \ncustom parameter types\n as well.\n\n\n\n\nAfter registering your routes\n\n\nAfter registering your routes you must register the Router as a \nGetting Started \n Services", 
            "title": "Routing"
        }, 
        {
            "location": "/getting-started/routing/#routing", 
            "text": "Routing is the process of finding the appropriate response to an incoming request.", 
            "title": "Routing"
        }, 
        {
            "location": "/getting-started/routing/#making-a-router", 
            "text": "In Vapor the default Router is the  EngineRouter . You can implement custom routers by implementing one conforming to the  Router  protocol.  let   router   =   try   EngineRouter . default ()   This is usually done in your  configure.swift  file.", 
            "title": "Making a Router"
        }, 
        {
            "location": "/getting-started/routing/#registering-a-route", 
            "text": "Imagine you want to return a list of users when someone visits  GET /users . Leaving authorization aside, that would look something like this.  router . get ( users )   {   req   in \n     return   // fetch the users  }   In Vapor, routing is usually done using the  .get ,  .put ,  .post ,  .patch  and  .delete  shorthands. You can supply the path as  /  or comma-separated strings. We recommend comma separated, as it's more readable.  router . get ( path ,   to ,   something )   {   ...   }", 
            "title": "Registering a route"
        }, 
        {
            "location": "/getting-started/routing/#routes", 
            "text": "The best place to add routes is in the  routes.swift  file. Use the router supplied as a parameter to this function to register your routes.  import   Vapor  public   func   routes ( _   router :   Router )   throws   { \n     // Basic  Hello, world!  example \n     router . get ( hello )   {   req   in \n         return   Hello, world! \n     } \n\n     /// ...  }   See  Getting Started   Content  for more information about what can be returned in a route closure.", 
            "title": "Routes"
        }, 
        {
            "location": "/getting-started/routing/#parameters", 
            "text": "Sometimes you may want one of the components of your route path to be dynamic. This is often used when\nyou want to get an item with a supplied identifier, e.g.,  GET /users/:id  router . get ( users ,   Int . parameter )   {   req   -   String   in \n     let   id   =   try   req . parameter ( Int . self ) \n     return   requested id # \\( id )  }   Instead of passing a string, pass the  type  of parameter you expect. In this case, our  User  has an  Int  ID.   Tip  You can define your own  custom parameter types  as well.", 
            "title": "Parameters"
        }, 
        {
            "location": "/getting-started/routing/#after-registering-your-routes", 
            "text": "After registering your routes you must register the Router as a  Getting Started   Services", 
            "title": "After registering your routes"
        }, 
        {
            "location": "/getting-started/content/", 
            "text": "Content\n\n\nIn Vapor 3, all content types (JSON, protobuf, URLEncodedForm, \nMultipart\n, etc) are treated the same. All you need to parse and serialize content is a \nCodable\n class or struct.\n\n\nFor this introduction, we will use JSON as an example. But keep in mind the API is the same for any supported content type.\n\n\nRequest\n\n\nLet's take a look at how you would parse the following HTTP request.\n\n\nPOST\n \n/login\n \nHTTP\n/\n1.1\n\n\nContent-Type\n:\n \napplication/json\n\n\n\n{\n\n    \nemail\n:\n \nuser@vapor.codes\n,\n\n    \npassword\n:\n \ndon\nt look!\n\n\n}\n\n\n\n\n\n\nFirst, create a struct or class that represents the data you expect.\n\n\nimport\n \nVapor\n\n\n\nstruct\n \nLoginRequest\n:\n \nContent\n \n{\n\n    \nvar\n \nemail\n:\n \nString\n\n    \nvar\n \npassword\n:\n \nString\n\n\n}\n\n\n\n\n\n\nThen simply conform this struct or class to \nContent\n.\nNow we are ready to decode that HTTP request.\n\n\nrouter\n.\npost\n(\nlogin\n)\n \n{\n \nreq\n \n-\n \nFuture\nHTTPStatus\n \nin\n\n    \nreturn\n \nreq\n.\ncontent\n.\ndecode\n(\nLoginRequest\n.\nself\n).\nmap\n(\nto\n:\n \nHTTPStatus\n.\nself\n)\n \n{\n \nloginRequest\n \nin\n\n        \nprint\n(\nloginRequest\n.\nemail\n)\n \n// user@vapor.codes\n\n        \nprint\n(\nloginRequest\n.\npassword\n)\n \n// don\nt look!\n\n        \nreturn\n \n.\nok\n\n    \n}\n\n\n}\n\n\n\n\n\n\nWe use \n.map(to:)\n here since \nreq.content.decode(_:)\n returns a \nfuture\n.\n\n\nResponse\n\n\nLet's take a look at how you would create the following HTTP response.\n\n\nHTTP\n/\n1.1\n \n200\n \nOK\n\n\nContent-Type\n:\n \napplication/json\n\n\n\n{\n\n    \nname\n:\n \nVapor User\n,\n\n    \nemail\n:\n \nuser@vapor.codes\n\n\n}\n\n\n\n\n\n\nJust like decoding, first create a struct or class that represents the data that you are expecting.\n\n\nimport\n \nVapor\n\n\n\nstruct\n \nUser\n:\n \nContent\n \n{\n\n    \nvar\n \nname\n:\n \nString\n\n    \nvar\n \nemail\n:\n \nString\n\n\n}\n\n\n\n\n\n\nThen just conform this struct or class to \nContent\n. Now we are ready to encode that HTTP response.\n\n\nrouter\n.\nget\n(\nuser\n)\n \n{\n \nreq\n \n-\n \nUser\n \nin\n\n    \nreturn\n \nUser\n(\n\n        \nname\n:\n \nVapor User\n,\n\n        \nemail\n:\n \nuser@vapor.codes\n\n    \n)\n\n\n}\n\n\n\n\n\n\nGreat job! Now you know how to encode and decode data in Vapor. \n\n\n\n\nTip\n\n\nSee \nVapor \n Content\n for more in-depth information.\n\n\n\n\nThe next section in this guide is \nAsync\n.", 
            "title": "Content"
        }, 
        {
            "location": "/getting-started/content/#content", 
            "text": "In Vapor 3, all content types (JSON, protobuf, URLEncodedForm,  Multipart , etc) are treated the same. All you need to parse and serialize content is a  Codable  class or struct.  For this introduction, we will use JSON as an example. But keep in mind the API is the same for any supported content type.", 
            "title": "Content"
        }, 
        {
            "location": "/getting-started/content/#request", 
            "text": "Let's take a look at how you would parse the following HTTP request.  POST   /login   HTTP / 1.1  Content-Type :   application/json  { \n     email :   user@vapor.codes , \n     password :   don t look!  }   First, create a struct or class that represents the data you expect.  import   Vapor  struct   LoginRequest :   Content   { \n     var   email :   String \n     var   password :   String  }   Then simply conform this struct or class to  Content .\nNow we are ready to decode that HTTP request.  router . post ( login )   {   req   -   Future HTTPStatus   in \n     return   req . content . decode ( LoginRequest . self ). map ( to :   HTTPStatus . self )   {   loginRequest   in \n         print ( loginRequest . email )   // user@vapor.codes \n         print ( loginRequest . password )   // don t look! \n         return   . ok \n     }  }   We use  .map(to:)  here since  req.content.decode(_:)  returns a  future .", 
            "title": "Request"
        }, 
        {
            "location": "/getting-started/content/#response", 
            "text": "Let's take a look at how you would create the following HTTP response.  HTTP / 1.1   200   OK  Content-Type :   application/json  { \n     name :   Vapor User , \n     email :   user@vapor.codes  }   Just like decoding, first create a struct or class that represents the data that you are expecting.  import   Vapor  struct   User :   Content   { \n     var   name :   String \n     var   email :   String  }   Then just conform this struct or class to  Content . Now we are ready to encode that HTTP response.  router . get ( user )   {   req   -   User   in \n     return   User ( \n         name :   Vapor User , \n         email :   user@vapor.codes \n     )  }   Great job! Now you know how to encode and decode data in Vapor.    Tip  See  Vapor   Content  for more in-depth information.   The next section in this guide is  Async .", 
            "title": "Response"
        }, 
        {
            "location": "/getting-started/async/", 
            "text": "Async\n\n\nYou may have noticed some APIs in Vapor expect or return a generic \nFuture\n type. If this is your first time hearing about futures, they might seem a little confusing at first. But don't worry, Vapor makes them easy to use.\n\n\nThis guide will give you a quick introduction to working with Async. Check out \nAsync \u2192 Overview\n for more information.\n\n\nFutures\n\n\nSince \nFuture\ns work asynchronously, we must use closures to interact with and transform their values. Just like optionals in Swift, futures can be mapped and flat-mapped. \n\n\nMap\n\n\nThe \n.map(to:_:)\n method allows you to transform the future's value to another value. The closure provided will be called once the \nFuture\n's data becomes available. \n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\n/// Map the future string to an integer\n\n\nlet\n \nfutureInt\n \n=\n \nfutureString\n.\nmap\n(\nto\n:\n \nInt\n.\nself\n)\n \n{\n \nstring\n \nin\n\n    \nprint\n(\nstring\n)\n \n// The actual String\n\n    \nreturn\n \nInt\n(\nstring\n)\n \n??\n \n0\n\n\n}\n\n\n\n/// We now have a future integer\n\n\nprint\n(\nfutureInt\n)\n \n// Future\nInt\n\n\n\n\n\n\nFlat Map\n\n\nThe \n.flatMap(to:_:)\n method allows you to transform the future's value to another future value. It gets the name \"flat\" map because it is what allows you to avoid creating nested futures (e.g., \nFuture\nFuture\nT\n). In other words, it helps you keep your futures flat.\n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\n/// Assume we have created an HTTP client\n\n\nlet\n \nclient\n:\n \nClient\n \n=\n \n...\n \n\n\n/// Flat-map the future string to a future response\n\n\nlet\n \nfutureResponse\n \n=\n \nfutureString\n.\nflatMap\n(\nto\n:\n \nResponse\n.\nself\n)\n \n{\n \nstring\n \nin\n\n    \nreturn\n \nclient\n.\nget\n(\nstring\n)\n \n// Future\nResponse\n\n\n}\n\n\n\n/// We now have a future response\n\n\nprint\n(\nfutureResponse\n)\n \n// Future\nResponse\n\n\n\n\n\n\n\n\nInfo\n\n\nIf we instead used \n.map(to:_:)\n in the above example, we would have ended up with a \nFuture\nFuture\nResponse\n. Yikes!\n\n\n\n\nChaining\n\n\nThe great part about transformations on futures is that they can be chained. This allows you to express many conversions and subtasks easily.\n\n\nLet's modify the examples from above to see how we can take advantage of chaining.\n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\n/// Assume we have created an HTTP client\n\n\nlet\n \nclient\n:\n \nClient\n \n=\n \n...\n \n\n\n/// Transform the string to a url, then to a response\n\n\nlet\n \nfutureResponse\n \n=\n \nfutureString\n.\nmap\n(\nto\n:\n \nURL\n.\nself\n)\n \n{\n \nstring\n \nin\n\n    \nguard\n \nlet\n \nurl\n \n=\n \nURL\n(\nstring\n:\n \nstring\n)\n \nelse\n \n{\n\n        \nthrow\n \nAbort\n(.\nbadRequest\n,\n \nreason\n:\n \nInvalid URL string: \n\\(\nstring\n)\n)\n\n    \n}\n\n    \nreturn\n \nurl\n\n\n}.\nflatMap\n(\nto\n:\n \nResponse\n.\nself\n)\n \n{\n \nurl\n \nin\n\n    \nreturn\n \nclient\n.\nget\n(\nurl\n)\n\n\n}\n\n\n\nprint\n(\nfutureResponse\n)\n \n// Future\nResponse\n\n\n\n\n\n\nAfter the initial call to map, there is a temporary \nFuture\nURL\n created. This future is then immediately flat-mapped to a \nFuture\nResponse\n\n\n\n\nTip\n\n\nYou can \nthrow\n errors inside of map and flat-map closures. This will result in the future failing with the error thrown.\n\n\n\n\nWorker\n\n\nYou may see methods in Vapor that have an \non: Worker\n parameter. These are usually methods that perform asynchronous work and require access to the \nEventLoop\n.\n\n\nThe most common \nWorker\ns you will interact with in Vapor are:\n\n\n\n\nApplication\n\n\nRequest\n\n\nResponse\n\n\n\n\n/// Assume we have a Request and some ViewRenderer\n\n\nlet\n \nreq\n:\n \nRequest\n \n=\n \n...\n\n\nlet\n \nview\n:\n \nViewRenderer\n \n=\n \n...\n\n\n\n/// Render the view, using the Request as a worker. \n\n\n/// This ensures the async work happens on the correct event loop.\n\n\n///\n\n\n/// This assumes the signature is:\n\n\n/// func render(_: String, on: Worker)\n\n\nview\n.\nrender\n(\nhome.html\n,\n \non\n:\n \nreq\n)", 
            "title": "Async"
        }, 
        {
            "location": "/getting-started/async/#async", 
            "text": "You may have noticed some APIs in Vapor expect or return a generic  Future  type. If this is your first time hearing about futures, they might seem a little confusing at first. But don't worry, Vapor makes them easy to use.  This guide will give you a quick introduction to working with Async. Check out  Async \u2192 Overview  for more information.", 
            "title": "Async"
        }, 
        {
            "location": "/getting-started/async/#futures", 
            "text": "Since  Future s work asynchronously, we must use closures to interact with and transform their values. Just like optionals in Swift, futures can be mapped and flat-mapped.", 
            "title": "Futures"
        }, 
        {
            "location": "/getting-started/async/#map", 
            "text": "The  .map(to:_:)  method allows you to transform the future's value to another value. The closure provided will be called once the  Future 's data becomes available.   /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  /// Map the future string to an integer  let   futureInt   =   futureString . map ( to :   Int . self )   {   string   in \n     print ( string )   // The actual String \n     return   Int ( string )   ??   0  }  /// We now have a future integer  print ( futureInt )   // Future Int", 
            "title": "Map"
        }, 
        {
            "location": "/getting-started/async/#flat-map", 
            "text": "The  .flatMap(to:_:)  method allows you to transform the future's value to another future value. It gets the name \"flat\" map because it is what allows you to avoid creating nested futures (e.g.,  Future Future T ). In other words, it helps you keep your futures flat.  /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  /// Assume we have created an HTTP client  let   client :   Client   =   ...   /// Flat-map the future string to a future response  let   futureResponse   =   futureString . flatMap ( to :   Response . self )   {   string   in \n     return   client . get ( string )   // Future Response  }  /// We now have a future response  print ( futureResponse )   // Future Response    Info  If we instead used  .map(to:_:)  in the above example, we would have ended up with a  Future Future Response . Yikes!", 
            "title": "Flat Map"
        }, 
        {
            "location": "/getting-started/async/#chaining", 
            "text": "The great part about transformations on futures is that they can be chained. This allows you to express many conversions and subtasks easily.  Let's modify the examples from above to see how we can take advantage of chaining.  /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  /// Assume we have created an HTTP client  let   client :   Client   =   ...   /// Transform the string to a url, then to a response  let   futureResponse   =   futureString . map ( to :   URL . self )   {   string   in \n     guard   let   url   =   URL ( string :   string )   else   { \n         throw   Abort (. badRequest ,   reason :   Invalid URL string:  \\( string ) ) \n     } \n     return   url  }. flatMap ( to :   Response . self )   {   url   in \n     return   client . get ( url )  }  print ( futureResponse )   // Future Response   After the initial call to map, there is a temporary  Future URL  created. This future is then immediately flat-mapped to a  Future Response   Tip  You can  throw  errors inside of map and flat-map closures. This will result in the future failing with the error thrown.", 
            "title": "Chaining"
        }, 
        {
            "location": "/getting-started/async/#worker", 
            "text": "You may see methods in Vapor that have an  on: Worker  parameter. These are usually methods that perform asynchronous work and require access to the  EventLoop .  The most common  Worker s you will interact with in Vapor are:   Application  Request  Response   /// Assume we have a Request and some ViewRenderer  let   req :   Request   =   ...  let   view :   ViewRenderer   =   ...  /// Render the view, using the Request as a worker.   /// This ensures the async work happens on the correct event loop.  ///  /// This assumes the signature is:  /// func render(_: String, on: Worker)  view . render ( home.html ,   on :   req )", 
            "title": "Worker"
        }, 
        {
            "location": "/getting-started/services/", 
            "text": "Services\n\n\nServices is a dependency injection (also called inversion of control) framework for Vapor. The services framework allows you to register, configure, and initialize anything you might need in your application.\n\n\nContainer\n\n\nMost of your interaction with services will happen through a container. A container is a combination of the following:\n\n\n\n\nServices\n: A collection of registered services.\n\n\nConfig\n: Declared preferences for certain services over others.\n\n\nEnvironment\n: The application's current environment type (testing, production, etc)\n\n\nWorker\n: The event loop associated with this container.\n\n\n\n\nThe most common containers you will interact with in Vapor are:\n\n\n\n\nApplication\n\n\nRequest\n\n\nResponse\n\n\n\n\nYou should use the \nApplication\n as a container to create services required for booting your app. You should use the \nRequest\n or \nResponse\n containers to create services for responding to requests (in route closures and controllers).\n\n\nMake\n\n\nMaking services is simple, just call \n.make(_:)\n on a container and pass the type you want, usually a protocol like \nClient\n.\n\n\nlet\n \nclient\n \n=\n \ntry\n \nreq\n.\nmake\n(\nClient\n.\nself\n)\n\n\n\n\n\n\nYou can also specify a concrete type if you know exactly what you want.\n\n\nlet\n \nleaf\n \n=\n \ntry\n \nreq\n.\nmake\n(\nLeafRenderer\n.\nself\n)\n\n\nprint\n(\nleaf\n)\n \n/// Definitely a LeafRenderer\n\n\n\nlet\n \nview\n \n=\n \ntry\n \nreq\n.\nmake\n(\nViewRenderer\n.\nself\n)\n\n\nprint\n(\nview\n)\n \n/// ViewRenderer, might be a LeafRenderer\n\n\n\n\n\n\n\n\nTip\n\n\nTry to rely on protocols over concrete types if you can. This will make testing your code easier (you can easily swap in dummy implementations) and it can help keep your code decoupled.\n\n\n\n\nServices\n\n\nThe \nServices\n struct contains all of the services you\nor the service providers you have added\nhave registered. You will usually register and configure your services in  \nconfigure.swift\n.\n\n\nInstance\n\n\nYou can register initialized service instances using \n.register(_:)\n.\n\n\n/// Create an in-memory SQLite database\n\n\nlet\n \nsqlite\n \n=\n \nSQLiteDatabase\n(\nstorage\n:\n \n.\nmemory\n)\n\n\n\n/// Register to sevices.\n\n\nservices\n.\nregister\n(\nsqlite\n)\n\n\n\n\n\n\nAfter you register a service, it will be available for creation by a \nContainer\n. \n\n\nlet\n \ndb\n \n=\n \napp\n.\nmake\n(\nSQLiteDatabase\n.\nself\n)\n\n\nprint\n(\ndb\n)\n \n// SQLiteDatabase (the one we registered earlier)\n\n\n\n\n\n\nProtocol\n\n\nWhen registering services, you can also declare conformance to a particular protocol. You might have noticed that this is how Vapor registers its main router.\n\n\n/// Register routes to the router\n\n\nlet\n \nrouter\n \n=\n \nEngineRouter\n.\ndefault\n()\n\n\ntry\n \nroutes\n(\nrouter\n)\n\n\nservices\n.\nregister\n(\nrouter\n,\n \nas\n:\n \nRouter\n.\nself\n)\n\n\n\n\n\n\nSince we register the \nrouter\n variable with \nas: Router.self\n, it can be created using either the concrete type or the protocol.\n\n\nlet\n \nrouter\n \n=\n \napp\n.\nmake\n(\nRouter\n.\nself\n)\n\n\nlet\n \nengineRouter\n \n=\n \napp\n.\nmake\n(\nEngineRouter\n.\nself\n)\n\n\nprint\n(\nrouter\n)\n \n// Router (actually EngineRouter)\n\n\nprint\n(\nengineRouter\n)\n \n// EngineRouter\n\n\nprint\n(\nrouter\n \n===\n \nengineRouter\n)\n \n// true\n\n\n\n\n\n\nEnvironment\n\n\nThe environment is used to dynamically change how your Vapor app behaves in certain situations. For example, you probably want to use a different username and password for your database when your application is deployed. The \nEnvironment\n type makes managing this easy.\n\n\nWhen you run your Vapor app from the command line, you can pass an optional \n--env\n flag to specify the environment. By default, the environment will be \n.development\n.\n\n\nswift run Run --env prod\n\n\n\n\n\nIn the above example, we are running Vapor in the \n.production\n environment. This environment specifies \nisRelease = true\n.\n\n\nYou can use the environment passed into \nconfigure.swift\n to dynamically register services.\n\n\nlet\n \nsqlite\n:\n \nSQLiteDatabase\n\n\nif\n \nenv\n.\nisRelease\n \n{\n\n    \n/// Create file-based SQLite db using $SQLITE_PATH from process env\n\n    \nsqlite\n \n=\n \ntry\n \nSQLiteDatabase\n(\nstorage\n:\n \n.\nfile\n(\npath\n:\n \nEnvironment\n.\nget\n(\nSQLITE_PATH\n)\n!\n))\n\n\n}\n \nelse\n \n{\n\n    \n/// Create an in-memory SQLite database\n\n    \nsqlite\n \n=\n \ntry\n \nSQLiteDatabase\n(\nstorage\n:\n \n.\nmemory\n)\n\n\n}\n\n\nservices\n.\nregister\n(\nsqlite\n)\n\n\n\n\n\n\n\n\nInfo\n\n\nUse the static method \nEnvironment.get(_:)\n to fetch string values from the process environment.\n\n\n\n\nYou can also dynamically register services based on environment using the factory \n.register(_:)\n method.\n\n\nservices\n.\nregister\n \n{\n \ncontainer\n \n-\n \nBCryptConfig\n \nin\n\n  \nlet\n \ncost\n:\n \nInt\n\n\n  \nswitch\n \ncontainer\n.\nenvironment\n \n{\n\n  \ncase\n \n.\nproduction\n:\n \ncost\n \n=\n \n12\n\n  \ndefault\n:\n \ncost\n \n=\n \n4\n\n  \n}\n\n\n  \nreturn\n \nBCryptConfig\n(\ncost\n:\n \ncost\n)\n\n\n}\n\n\n\n\n\n\nConfig\n\n\nIf multiple services are available for a given protocol, you will need to use the \nConfig\n struct to declare which service you prefer.\n\n\nServiceError.ambiguity: Please choose which KeyedCache you prefer, multiple are available: MemoryKeyedCache, FluentCache\nSQLiteDatabase\n.\n\n\n\n\n\nThis is also done in \nconfigure.swift\n, just use the \nconfig.prefer(_:for:)\n method.\n\n\n/// Declare preference for MemoryKeyedCache anytime a container is asked to create a KeyedCache\n\n\nconfig\n.\nprefer\n(\nMemoryKeyedCache\n.\nself\n,\n \nfor\n:\n \nKeyedCache\n.\nself\n)\n\n\n\n/// ...\n\n\n\n/// Create a KeyedCache using the Request container\n\n\nlet\n \ncache\n \n=\n \nreq\n.\nmake\n(\nKeyedCache\n.\nself\n)\n\n\nprint\n(\ncache\n \nis\n \nMemoryKeyedCache\n)\n \n// true", 
            "title": "Services"
        }, 
        {
            "location": "/getting-started/services/#services", 
            "text": "Services is a dependency injection (also called inversion of control) framework for Vapor. The services framework allows you to register, configure, and initialize anything you might need in your application.", 
            "title": "Services"
        }, 
        {
            "location": "/getting-started/services/#container", 
            "text": "Most of your interaction with services will happen through a container. A container is a combination of the following:   Services : A collection of registered services.  Config : Declared preferences for certain services over others.  Environment : The application's current environment type (testing, production, etc)  Worker : The event loop associated with this container.   The most common containers you will interact with in Vapor are:   Application  Request  Response   You should use the  Application  as a container to create services required for booting your app. You should use the  Request  or  Response  containers to create services for responding to requests (in route closures and controllers).", 
            "title": "Container"
        }, 
        {
            "location": "/getting-started/services/#make", 
            "text": "Making services is simple, just call  .make(_:)  on a container and pass the type you want, usually a protocol like  Client .  let   client   =   try   req . make ( Client . self )   You can also specify a concrete type if you know exactly what you want.  let   leaf   =   try   req . make ( LeafRenderer . self )  print ( leaf )   /// Definitely a LeafRenderer  let   view   =   try   req . make ( ViewRenderer . self )  print ( view )   /// ViewRenderer, might be a LeafRenderer    Tip  Try to rely on protocols over concrete types if you can. This will make testing your code easier (you can easily swap in dummy implementations) and it can help keep your code decoupled.", 
            "title": "Make"
        }, 
        {
            "location": "/getting-started/services/#services_1", 
            "text": "The  Services  struct contains all of the services you or the service providers you have added have registered. You will usually register and configure your services in   configure.swift .", 
            "title": "Services"
        }, 
        {
            "location": "/getting-started/services/#instance", 
            "text": "You can register initialized service instances using  .register(_:) .  /// Create an in-memory SQLite database  let   sqlite   =   SQLiteDatabase ( storage :   . memory )  /// Register to sevices.  services . register ( sqlite )   After you register a service, it will be available for creation by a  Container .   let   db   =   app . make ( SQLiteDatabase . self )  print ( db )   // SQLiteDatabase (the one we registered earlier)", 
            "title": "Instance"
        }, 
        {
            "location": "/getting-started/services/#protocol", 
            "text": "When registering services, you can also declare conformance to a particular protocol. You might have noticed that this is how Vapor registers its main router.  /// Register routes to the router  let   router   =   EngineRouter . default ()  try   routes ( router )  services . register ( router ,   as :   Router . self )   Since we register the  router  variable with  as: Router.self , it can be created using either the concrete type or the protocol.  let   router   =   app . make ( Router . self )  let   engineRouter   =   app . make ( EngineRouter . self )  print ( router )   // Router (actually EngineRouter)  print ( engineRouter )   // EngineRouter  print ( router   ===   engineRouter )   // true", 
            "title": "Protocol"
        }, 
        {
            "location": "/getting-started/services/#environment", 
            "text": "The environment is used to dynamically change how your Vapor app behaves in certain situations. For example, you probably want to use a different username and password for your database when your application is deployed. The  Environment  type makes managing this easy.  When you run your Vapor app from the command line, you can pass an optional  --env  flag to specify the environment. By default, the environment will be  .development .  swift run Run --env prod  In the above example, we are running Vapor in the  .production  environment. This environment specifies  isRelease = true .  You can use the environment passed into  configure.swift  to dynamically register services.  let   sqlite :   SQLiteDatabase  if   env . isRelease   { \n     /// Create file-based SQLite db using $SQLITE_PATH from process env \n     sqlite   =   try   SQLiteDatabase ( storage :   . file ( path :   Environment . get ( SQLITE_PATH ) ! ))  }   else   { \n     /// Create an in-memory SQLite database \n     sqlite   =   try   SQLiteDatabase ( storage :   . memory )  }  services . register ( sqlite )    Info  Use the static method  Environment.get(_:)  to fetch string values from the process environment.   You can also dynamically register services based on environment using the factory  .register(_:)  method.  services . register   {   container   -   BCryptConfig   in \n   let   cost :   Int \n\n   switch   container . environment   { \n   case   . production :   cost   =   12 \n   default :   cost   =   4 \n   } \n\n   return   BCryptConfig ( cost :   cost )  }", 
            "title": "Environment"
        }, 
        {
            "location": "/getting-started/services/#config", 
            "text": "If multiple services are available for a given protocol, you will need to use the  Config  struct to declare which service you prefer.  ServiceError.ambiguity: Please choose which KeyedCache you prefer, multiple are available: MemoryKeyedCache, FluentCache SQLiteDatabase .  This is also done in  configure.swift , just use the  config.prefer(_:for:)  method.  /// Declare preference for MemoryKeyedCache anytime a container is asked to create a KeyedCache  config . prefer ( MemoryKeyedCache . self ,   for :   KeyedCache . self )  /// ...  /// Create a KeyedCache using the Request container  let   cache   =   req . make ( KeyedCache . self )  print ( cache   is   MemoryKeyedCache )   // true", 
            "title": "Config"
        }, 
        {
            "location": "/getting-started/cloud/", 
            "text": "Deployment\n\n\nDeploying code is the process of making your Vapor project publically available. \nIt can be one of the most difficult aspects of web development. Fortunately, there\nare services to help.\n\n\nVapor Cloud\n\n\nThe best way to deploy your application is through Vapor Cloud. It's a cloud platform built\nspecifically for the Vapor web framework. This means it's incredibly easy to deploy your\nproject quickly and be confident that it will be fast and stable.\n\n\nDeploying your project to Vapor Cloud is simple, it's built right into the \nVapor Toolbox\n.\nJust run this command from within the root directory of your project.\n\n\nvapor cloud deploy\n\n\n\n\n\nFor a detailed guide, visit \nVapor Cloud \n Quick Start\n.\n\n\nOther Options\n\n\nVapor can be deployed anywhere that supports Ubuntu (basically everywhere). Guides on deploying to other systems are coming soon (contributions welcome)!", 
            "title": "Deployment"
        }, 
        {
            "location": "/getting-started/cloud/#deployment", 
            "text": "Deploying code is the process of making your Vapor project publically available. \nIt can be one of the most difficult aspects of web development. Fortunately, there\nare services to help.", 
            "title": "Deployment"
        }, 
        {
            "location": "/getting-started/cloud/#vapor-cloud", 
            "text": "The best way to deploy your application is through Vapor Cloud. It's a cloud platform built\nspecifically for the Vapor web framework. This means it's incredibly easy to deploy your\nproject quickly and be confident that it will be fast and stable.  Deploying your project to Vapor Cloud is simple, it's built right into the  Vapor Toolbox .\nJust run this command from within the root directory of your project.  vapor cloud deploy  For a detailed guide, visit  Vapor Cloud   Quick Start .", 
            "title": "Vapor Cloud"
        }, 
        {
            "location": "/getting-started/cloud/#other-options", 
            "text": "Vapor can be deployed anywhere that supports Ubuntu (basically everywhere). Guides on deploying to other systems are coming soon (contributions welcome)!", 
            "title": "Other Options"
        }, 
        {
            "location": "/async/getting-started/", 
            "text": "Getting Started with Async\n\n\nThe Async module is provided as a part of Vapor Core (\nvapor/core\n). It is a collection of convenience APIs (mostly extensions) built on top of \nSwiftNIO\n.\n\n\n\n\nTip\n\n\nYou can read more about SwiftNIO's async types (\nFuture\n,  \nPromise\n, \nEventLoop\n, and more) in its GitHub \nREADME\n or its \nAPI Docs\n.\n\n\n\n\nUsage\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nAsync\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n \n// implies `import Async`\n\n\n\n\n\n\nStandalone\n\n\nThe Async module, part of the larger Vapor Core package, can also be used on its own with any Swift project.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/core.git\n,\n \nfrom\n:\n \n3.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nAsync\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Async\n to access the APIs.\n\n\nOverview\n\n\nContinue to \nAsync \n Overview\n for an overview of Async's features.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/async/getting-started/#getting-started-with-async", 
            "text": "The Async module is provided as a part of Vapor Core ( vapor/core ). It is a collection of convenience APIs (mostly extensions) built on top of  SwiftNIO .   Tip  You can read more about SwiftNIO's async types ( Future ,   Promise ,  EventLoop , and more) in its GitHub  README  or its  API Docs .", 
            "title": "Getting Started with Async"
        }, 
        {
            "location": "/async/getting-started/#usage", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  Async  APIs when you import  Vapor .  import   Vapor   // implies `import Async`", 
            "title": "Usage"
        }, 
        {
            "location": "/async/getting-started/#standalone", 
            "text": "The Async module, part of the larger Vapor Core package, can also be used on its own with any Swift project.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/core.git ,   from :   3.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Async ,   ...   ]) \n     ]  )   Use  import Async  to access the APIs.", 
            "title": "Standalone"
        }, 
        {
            "location": "/async/getting-started/#overview", 
            "text": "Continue to  Async   Overview  for an overview of Async's features.", 
            "title": "Overview"
        }, 
        {
            "location": "/async/overview/", 
            "text": "Async Overview\n\n\nYou may have noticed some APIs in Vapor expect or return a generic \nFuture\n type. If this is your first time hearing about futures, they might seem a little confusing at first. But don't worry, Vapor makes them easy to use.\n\n\nPromises and futures are related, but distinct, types. Promises are used to \ncreate\n futures. Most of the time, you will be working with futures returned by Vapor's APIs and you will not need to worry about creating promises.\n\n\n\n\n\n\n\n\ntype\n\n\ndescription\n\n\nmutability\n\n\nmethods\n\n\n\n\n\n\n\n\n\n\nFuture\n\n\nReference to an object that may not be available yet.\n\n\nread-only\n\n\n.map(to:_:)\n \n.flatMap(to:_:)\n \ndo(_:)\n \ncatch(_:)\n\n\n\n\n\n\nPromise\n\n\nA promise to provide some object asynchronously.\n\n\nread/write\n\n\nsucceed(_:)\n \nfail(_:)\n\n\n\n\n\n\n\n\nFutures are an alternative to callback-based asynchronous APIs. Futures can be chained and transformed in ways that simple closures cannot, making them quite powerful.\n\n\nTransforming\n\n\nJust like optionals in Swift, futures can be mapped and flat-mapped. These are the most common operations you will perform on futures.\n\n\n\n\n\n\n\n\nmethod\n\n\nsignature\n\n\ndescription\n\n\n\n\n\n\n\n\n\n\nmap\n\n\nto: U.Type, _: (T) -\n U\n\n\nMaps a future value to a different value.\n\n\n\n\n\n\nflatMap\n\n\nto: U.Type, _: (T) -\n Future\nU\n\n\nMaps a future value to different \nfuture\n value.\n\n\n\n\n\n\ntransform\n\n\nto: U\n\n\nMaps a future to an already available value.\n\n\n\n\n\n\n\n\nIf you look at the method signatures for \nmap\n and \nflatMap\n on \nOptional\nT\n and \nArray\nT\n, you will see that they are very similar to the methods available on \nFuture\nT\n.\n\n\nMap\n\n\nThe \n.map(to:_:)\n method allows you to transform the future's value to another value. Because the future's value may not be available yet (it may be the result of an asynchronous task) we must provide a closure to accept the value.\n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\n/// Map the future string to an integer\n\n\nlet\n \nfutureInt\n \n=\n \nfutureString\n.\nmap\n(\nto\n:\n \nInt\n.\nself\n)\n \n{\n \nstring\n \nin\n\n    \nprint\n(\nstring\n)\n \n// The actual String\n\n    \nreturn\n \nInt\n(\nstring\n)\n \n??\n \n0\n\n\n}\n\n\n\n/// We now have a future integer\n\n\nprint\n(\nfutureInt\n)\n \n// Future\nInt\n\n\n\n\n\n\nFlat Map\n\n\nThe \n.flatMap(to:_:)\n method allows you to transform the future's value to another future value. It gets the name \"flat\" map because it is what allows you to avoid creating nested futures (e.g., \nFuture\nFuture\nT\n). In other words, it helps you keep your generic futures flat.\n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\n/// Assume we have created an HTTP client\n\n\nlet\n \nclient\n:\n \nClient\n \n=\n \n...\n \n\n\n/// Flat-map the future string to a future response\n\n\nlet\n \nfutureResponse\n \n=\n \nfutureString\n.\nflatMap\n(\nto\n:\n \nResponse\n.\nself\n)\n \n{\n \nstring\n \nin\n\n    \nreturn\n \nclient\n.\nget\n(\nstring\n)\n \n// Future\nResponse\n\n\n}\n\n\n\n/// We now have a future response\n\n\nprint\n(\nfutureResponse\n)\n \n// Future\nResponse\n\n\n\n\n\n\n\n\nInfo\n\n\nIf we instead used \n.map(to:_:)\n in the above example, we would have ended up with a \nFuture\nFuture\nResponse\n. Yikes!\n\n\n\n\nTransform\n\n\nThe \n.transform(_:)\n method allows you to modify a future's value, ignoring the existing value. This is especially useful for transforming the results of \nFuture\nVoid\n where the actual value of the future is not important.\n\n\n\n\nTip\n\n\nFuture\nVoid\n, sometimes called a signal, is a future whose sole purpose is to notify you of completion or failure of some async operation.\n\n\n\n\n/// Assume we get a void future back from some API\n\n\nlet\n \nuserDidSave\n:\n \nFuture\nVoid\n \n=\n \n...\n\n\n\n/// Transform the void future to an HTTP status\n\n\nlet\n \nfutureStatus\n \n=\n \nuserDidSave\n.\ntransform\n(\nto\n:\n \nHTTPStatus\n.\nok\n)\n\n\nprint\n(\nfutureStatus\n)\n \n// Future\nHTTPStatus\n\n\n\n\n\n\nEven though we have supplied an already-available value to \ntransform\n, this is still a \ntransformation\n. The future will not complete until all previous futures have completed (or failed).\n\n\nChaining\n\n\nThe great part about transformations on futures is that they can be chained. This allows you to express many conversions and subtasks easily.\n\n\nLet's modify the examples from above to see how we can take advantage of chaining.\n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\n/// Assume we have created an HTTP client\n\n\nlet\n \nclient\n:\n \nClient\n \n=\n \n...\n \n\n\n/// Transform the string to a url, then to a response\n\n\nlet\n \nfutureResponse\n \n=\n \nfutureString\n.\nmap\n(\nto\n:\n \nURL\n.\nself\n)\n \n{\n \nstring\n \nin\n\n    \nguard\n \nlet\n \nurl\n \n=\n \nURL\n(\nstring\n:\n \nstring\n)\n \nelse\n \n{\n\n        \nthrow\n \nAbort\n(.\nbadRequest\n,\n \nreason\n:\n \nInvalid URL string: \n\\(\nstring\n)\n)\n\n    \n}\n\n    \nreturn\n \nurl\n\n\n}.\nflatMap\n(\nto\n:\n \nResponse\n.\nself\n)\n \n{\n \nurl\n \nin\n\n    \nreturn\n \nclient\n.\nget\n(\nurl\n)\n\n\n}\n\n\n\nprint\n(\nfutureResponse\n)\n \n// Future\nResponse\n\n\n\n\n\n\nAfter the initial call to map, there is a temporary \nFuture\nURL\n created. This future is then immediately flat-mapped to a \nFuture\nResponse\n\n\n\n\nTip\n\n\nYou can \nthrow\n errors inside of map and flat-map closures. This will result in the future failing with the error thrown.\n\n\n\n\nFuture\n\n\nLet's take a look at some other, less commonly used methods on \nFuture\nT\n.\n\n\nDo / Catch\n\n\nSimilar to Swift's \ndo\n / \ncatch\n syntax, futures have a \ndo\n and \ncatch\n method for awaiting the future's result.\n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\nfutureString\n.\ndo\n \n{\n \nstring\n \nin\n\n    \nprint\n(\nstring\n)\n \n// The actual String\n\n\n}.\ncatch\n \n{\n \nerror\n \nin\n\n    \nprint\n(\nerror\n)\n \n// A Swift Error\n\n\n}\n\n\n\n\n\n\n\n\nInfo\n\n\n.do\n and \n.catch\n work together. If you forget \n.catch\n, the compiler will warn you about an unused result. Don't forget to handle the error case!\n\n\n\n\nAlways\n\n\nYou can use \nalways\n to add a callback that will be executed whether the future succeeds or fails.\n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\nfutureString\n.\nalways\n \n{\n\n    \nprint\n(\nThe future is complete!\n)\n\n\n}\n\n\n\n\n\n\n\n\nNote\n\n\nYou can add as many callbacks to a future as you want.\n\n\n\n\nWait\n\n\nYou can use \n.wait()\n to synchronously wait for the future to be completed. Since a future may fail, this call is throwing.\n\n\n/// Assume we get a future string back from some API\n\n\nlet\n \nfutureString\n:\n \nFuture\nString\n \n=\n \n...\n\n\n\n/// Block until the string is ready\n\n\nlet\n \nstring\n \n=\n \ntry\n \nfutureString\n.\nwait\n()\n\n\nprint\n(\nstring\n)\n \n/// String\n\n\n\n\n\n\n\n\nWarning\n\n\nDo not use this method in route closures or controllers. Read the section about \nBlocking\n for more information.\n\n\n\n\nPromise\n\n\nMost of the time, you will be transforming futures returned by calls to Vapor's APIs. However, at some point you may need to create a promise of your own.\n\n\nTo create a promise, you will need access to an \nEventLoop\n. All containers in Vapor have an \neventLoop\n property that you can use. Most commonly, this will be the current \nRequest\n.\n\n\n/// Create a new promise for some string\n\n\nlet\n \npromiseString\n \n=\n \nreq\n.\neventLoop\n.\nnewPromise\n(\nString\n.\nself\n)\n\n\nprint\n(\npromiseString\n)\n \n// Promise\nString\n\n\nprint\n(\npromiseString\n.\nfutureResult\n)\n \n// Future\nString\n\n\n\n/// Completes the associated future\n\n\npromiseString\n.\nsucceed\n(\nresult\n:\n \nHello\n)\n\n\n\n/// Fails the associated future\n\n\npromiseString\n.\nfail\n(\nerror\n:\n \n...)\n\n\n\n\n\n\n\n\nInfo\n\n\nA promise can only be completed once. Any subsequent completions will be ignored.\n\n\n\n\nThread Safety\n\n\nPromises can be completed (\nsucceed(result:)\n / \nfail(error:)\n) from any thread. This is why promises require an event-loop to be initialized. Promises ensure that the completion action gets returned to its event-loop for execution.\n\n\nEvent Loop\n\n\nWhen your application boots, it will usually create one event loop for each core in the CPU it is running on. Each event loop has exactly one thread. If you are familiar with event loops from Node.js, the ones in Vapor are very similar. The only difference is that Vapor can run multiple event loops in one process since Swift supports multi-threading.\n\n\nEach time a client connects to your server, it will be assigned to one of the event loops. From that point on, all communication between the server and that client will happen on that same event loop (and by association, that event loop's thread). \n\n\nThe event loop is responsible for keeping track of each connected client's state. If there is a request from the client waiting to be read, the event loop trigger a read notification, causing the data to be read. Once the entire request is read, any futures waiting for that request's data will be completed. \n\n\nWorker\n\n\nThings that have access to an event loop are called \nWorkers\n. Every container in Vapor is a worker. \n\n\nThe most common containers you will interact with in Vapor are:\n\n\n\n\nApplication\n\n\nRequest\n\n\nResponse\n\n\n\n\nYou can use the \n.eventLoop\n property on these containers to gain access to the event loop.\n\n\nprint\n(\napp\n.\neventLoop\n)\n \n// EventLoop\n\n\n\n\n\n\nThere are many methods in Vapor that require the current worker to be passed along. It will usually be labeled like \non: Worker\n. If you are in a route closure or a controller, pass the current \nRequest\n or \nResponse\n. If you need a worker while booting your app, use the \nApplication\n.\n\n\nBlocking\n\n\nAn absolutely critical rule is the following:\n\n\n\n\nDanger\n\n\nNever make blocking calls directly on an event loop.\n\n\n\n\nAn example of a blocking call would be something like \nlibc.sleep(_:)\n.\n\n\nrouter\n.\nget\n(\nhello\n)\n \n{\n \nreq\n \nin\n\n    \n/// Puts the event loop\ns thread to sleep.\n\n    \nsleep\n(\n5\n)\n\n\n    \n/// Returns a simple string once the thread re-awakens.\n\n    \nreturn\n \nHello, world!\n\n\n}\n\n\n\n\n\n\nsleep(_:)\n is a command that blocks the current thread for the number of seconds supplied. If you do blocking work directly on an event loop, the event loop will be unable to respond to any other clients assigned to it for the duration of the blocking work. In other words, if you do \nsleep(5)\n on an event loop, all of the other clients connected to that event loop (possibly hundreds or thousands) will be delayed for at least 5 seconds.\n\n\nMake sure to run any blocking work in the background. Use promises to notify the event loop when this work is done in a non-blocking way.\n\n\nrouter\n.\nget\n(\nhello\n)\n \n{\n \nreq\n \nin\n\n    \n/// Create a new void promise\n\n    \nlet\n \npromise\n \n=\n \nreq\n.\neventLoop\n.\nnewPromise\n(\nVoid\n.\nself\n)\n\n\n    \n/// Dispatch some work to happen on a background thread\n\n    \nDispatchQueue\n.\nglobal\n()\n \n{\n\n        \n/// Puts the background thread to sleep\n\n        \n/// This will not affect any of the event loops\n\n        \nsleep\n(\n5\n)\n\n\n        \n/// When the \nblocking work\n has completed,\n\n        \n/// complete the promise and its associated future.\n\n        \npromise\n.\nsucceed\n()\n\n    \n}\n\n\n    \n/// Wait for the future to be completed, \n\n    \n/// then transform the result to a simple String\n\n    \nreturn\n \npromise\n.\nfutureResult\n.\ntransform\n(\nto\n:\n \nHello, world!\n)\n\n\n}\n\n\n\n\n\n\nNot all blocking calls will be as obvious as \nsleep(_:)\n. If you are suspicious that a call you are using may be blocking, research the method itself or ask someone. Chances are if the function is doing disk or network IO and uses a synchronous API (no callbacks or futures) it is blocking.\n\n\n\n\nInfo\n\n\nIf doing blocking work is a central part of your application, you should consider using a \nBlockingIOThreadPool\n to control the number of threads you create to do blocking work. This will help you avoid starving your event loops from CPU time while blocking work is being done.", 
            "title": "Overview"
        }, 
        {
            "location": "/async/overview/#async-overview", 
            "text": "You may have noticed some APIs in Vapor expect or return a generic  Future  type. If this is your first time hearing about futures, they might seem a little confusing at first. But don't worry, Vapor makes them easy to use.  Promises and futures are related, but distinct, types. Promises are used to  create  futures. Most of the time, you will be working with futures returned by Vapor's APIs and you will not need to worry about creating promises.     type  description  mutability  methods      Future  Reference to an object that may not be available yet.  read-only  .map(to:_:)   .flatMap(to:_:)   do(_:)   catch(_:)    Promise  A promise to provide some object asynchronously.  read/write  succeed(_:)   fail(_:)     Futures are an alternative to callback-based asynchronous APIs. Futures can be chained and transformed in ways that simple closures cannot, making them quite powerful.", 
            "title": "Async Overview"
        }, 
        {
            "location": "/async/overview/#transforming", 
            "text": "Just like optionals in Swift, futures can be mapped and flat-mapped. These are the most common operations you will perform on futures.     method  signature  description      map  to: U.Type, _: (T) -  U  Maps a future value to a different value.    flatMap  to: U.Type, _: (T) -  Future U  Maps a future value to different  future  value.    transform  to: U  Maps a future to an already available value.     If you look at the method signatures for  map  and  flatMap  on  Optional T  and  Array T , you will see that they are very similar to the methods available on  Future T .", 
            "title": "Transforming"
        }, 
        {
            "location": "/async/overview/#map", 
            "text": "The  .map(to:_:)  method allows you to transform the future's value to another value. Because the future's value may not be available yet (it may be the result of an asynchronous task) we must provide a closure to accept the value.  /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  /// Map the future string to an integer  let   futureInt   =   futureString . map ( to :   Int . self )   {   string   in \n     print ( string )   // The actual String \n     return   Int ( string )   ??   0  }  /// We now have a future integer  print ( futureInt )   // Future Int", 
            "title": "Map"
        }, 
        {
            "location": "/async/overview/#flat-map", 
            "text": "The  .flatMap(to:_:)  method allows you to transform the future's value to another future value. It gets the name \"flat\" map because it is what allows you to avoid creating nested futures (e.g.,  Future Future T ). In other words, it helps you keep your generic futures flat.  /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  /// Assume we have created an HTTP client  let   client :   Client   =   ...   /// Flat-map the future string to a future response  let   futureResponse   =   futureString . flatMap ( to :   Response . self )   {   string   in \n     return   client . get ( string )   // Future Response  }  /// We now have a future response  print ( futureResponse )   // Future Response    Info  If we instead used  .map(to:_:)  in the above example, we would have ended up with a  Future Future Response . Yikes!", 
            "title": "Flat Map"
        }, 
        {
            "location": "/async/overview/#transform", 
            "text": "The  .transform(_:)  method allows you to modify a future's value, ignoring the existing value. This is especially useful for transforming the results of  Future Void  where the actual value of the future is not important.   Tip  Future Void , sometimes called a signal, is a future whose sole purpose is to notify you of completion or failure of some async operation.   /// Assume we get a void future back from some API  let   userDidSave :   Future Void   =   ...  /// Transform the void future to an HTTP status  let   futureStatus   =   userDidSave . transform ( to :   HTTPStatus . ok )  print ( futureStatus )   // Future HTTPStatus   Even though we have supplied an already-available value to  transform , this is still a  transformation . The future will not complete until all previous futures have completed (or failed).", 
            "title": "Transform"
        }, 
        {
            "location": "/async/overview/#chaining", 
            "text": "The great part about transformations on futures is that they can be chained. This allows you to express many conversions and subtasks easily.  Let's modify the examples from above to see how we can take advantage of chaining.  /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  /// Assume we have created an HTTP client  let   client :   Client   =   ...   /// Transform the string to a url, then to a response  let   futureResponse   =   futureString . map ( to :   URL . self )   {   string   in \n     guard   let   url   =   URL ( string :   string )   else   { \n         throw   Abort (. badRequest ,   reason :   Invalid URL string:  \\( string ) ) \n     } \n     return   url  }. flatMap ( to :   Response . self )   {   url   in \n     return   client . get ( url )  }  print ( futureResponse )   // Future Response   After the initial call to map, there is a temporary  Future URL  created. This future is then immediately flat-mapped to a  Future Response   Tip  You can  throw  errors inside of map and flat-map closures. This will result in the future failing with the error thrown.", 
            "title": "Chaining"
        }, 
        {
            "location": "/async/overview/#future", 
            "text": "Let's take a look at some other, less commonly used methods on  Future T .", 
            "title": "Future"
        }, 
        {
            "location": "/async/overview/#do-catch", 
            "text": "Similar to Swift's  do  /  catch  syntax, futures have a  do  and  catch  method for awaiting the future's result.  /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  futureString . do   {   string   in \n     print ( string )   // The actual String  }. catch   {   error   in \n     print ( error )   // A Swift Error  }    Info  .do  and  .catch  work together. If you forget  .catch , the compiler will warn you about an unused result. Don't forget to handle the error case!", 
            "title": "Do / Catch"
        }, 
        {
            "location": "/async/overview/#always", 
            "text": "You can use  always  to add a callback that will be executed whether the future succeeds or fails.  /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  futureString . always   { \n     print ( The future is complete! )  }    Note  You can add as many callbacks to a future as you want.", 
            "title": "Always"
        }, 
        {
            "location": "/async/overview/#wait", 
            "text": "You can use  .wait()  to synchronously wait for the future to be completed. Since a future may fail, this call is throwing.  /// Assume we get a future string back from some API  let   futureString :   Future String   =   ...  /// Block until the string is ready  let   string   =   try   futureString . wait ()  print ( string )   /// String    Warning  Do not use this method in route closures or controllers. Read the section about  Blocking  for more information.", 
            "title": "Wait"
        }, 
        {
            "location": "/async/overview/#promise", 
            "text": "Most of the time, you will be transforming futures returned by calls to Vapor's APIs. However, at some point you may need to create a promise of your own.  To create a promise, you will need access to an  EventLoop . All containers in Vapor have an  eventLoop  property that you can use. Most commonly, this will be the current  Request .  /// Create a new promise for some string  let   promiseString   =   req . eventLoop . newPromise ( String . self )  print ( promiseString )   // Promise String  print ( promiseString . futureResult )   // Future String  /// Completes the associated future  promiseString . succeed ( result :   Hello )  /// Fails the associated future  promiseString . fail ( error :   ...)    Info  A promise can only be completed once. Any subsequent completions will be ignored.", 
            "title": "Promise"
        }, 
        {
            "location": "/async/overview/#thread-safety", 
            "text": "Promises can be completed ( succeed(result:)  /  fail(error:) ) from any thread. This is why promises require an event-loop to be initialized. Promises ensure that the completion action gets returned to its event-loop for execution.", 
            "title": "Thread Safety"
        }, 
        {
            "location": "/async/overview/#event-loop", 
            "text": "When your application boots, it will usually create one event loop for each core in the CPU it is running on. Each event loop has exactly one thread. If you are familiar with event loops from Node.js, the ones in Vapor are very similar. The only difference is that Vapor can run multiple event loops in one process since Swift supports multi-threading.  Each time a client connects to your server, it will be assigned to one of the event loops. From that point on, all communication between the server and that client will happen on that same event loop (and by association, that event loop's thread).   The event loop is responsible for keeping track of each connected client's state. If there is a request from the client waiting to be read, the event loop trigger a read notification, causing the data to be read. Once the entire request is read, any futures waiting for that request's data will be completed.", 
            "title": "Event Loop"
        }, 
        {
            "location": "/async/overview/#worker", 
            "text": "Things that have access to an event loop are called  Workers . Every container in Vapor is a worker.   The most common containers you will interact with in Vapor are:   Application  Request  Response   You can use the  .eventLoop  property on these containers to gain access to the event loop.  print ( app . eventLoop )   // EventLoop   There are many methods in Vapor that require the current worker to be passed along. It will usually be labeled like  on: Worker . If you are in a route closure or a controller, pass the current  Request  or  Response . If you need a worker while booting your app, use the  Application .", 
            "title": "Worker"
        }, 
        {
            "location": "/async/overview/#blocking", 
            "text": "An absolutely critical rule is the following:   Danger  Never make blocking calls directly on an event loop.   An example of a blocking call would be something like  libc.sleep(_:) .  router . get ( hello )   {   req   in \n     /// Puts the event loop s thread to sleep. \n     sleep ( 5 ) \n\n     /// Returns a simple string once the thread re-awakens. \n     return   Hello, world!  }   sleep(_:)  is a command that blocks the current thread for the number of seconds supplied. If you do blocking work directly on an event loop, the event loop will be unable to respond to any other clients assigned to it for the duration of the blocking work. In other words, if you do  sleep(5)  on an event loop, all of the other clients connected to that event loop (possibly hundreds or thousands) will be delayed for at least 5 seconds.  Make sure to run any blocking work in the background. Use promises to notify the event loop when this work is done in a non-blocking way.  router . get ( hello )   {   req   in \n     /// Create a new void promise \n     let   promise   =   req . eventLoop . newPromise ( Void . self ) \n\n     /// Dispatch some work to happen on a background thread \n     DispatchQueue . global ()   { \n         /// Puts the background thread to sleep \n         /// This will not affect any of the event loops \n         sleep ( 5 ) \n\n         /// When the  blocking work  has completed, \n         /// complete the promise and its associated future. \n         promise . succeed () \n     } \n\n     /// Wait for the future to be completed,  \n     /// then transform the result to a simple String \n     return   promise . futureResult . transform ( to :   Hello, world! )  }   Not all blocking calls will be as obvious as  sleep(_:) . If you are suspicious that a call you are using may be blocking, research the method itself or ask someone. Chances are if the function is doing disk or network IO and uses a synchronous API (no callbacks or futures) it is blocking.   Info  If doing blocking work is a central part of your application, you should consider using a  BlockingIOThreadPool  to control the number of threads you create to do blocking work. This will help you avoid starving your event loops from CPU time while blocking work is being done.", 
            "title": "Blocking"
        }, 
        {
            "location": "/console/getting-started/", 
            "text": "Getting Started with Console\n\n\nThe Console module is provided as a part of Vapor's Console package (\nvapor/console\n).  This module provides APIs for performing console I/O including things like outputting stylized text, requesting user input, and displaying activity indicators like loading bars.\n\n\n\n\nTip\n\n\nFor an in-depth look at all of Console's APIs, check out the \nConsole API docs\n.\n\n\n\n\nUsage\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nConsole\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n \n// implies import Console\n\n\n\n\n\n\nStandalone\n\n\nThe Console module, part of the larger Vapor Console package, can also be used on its own with any Swift project.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n/// \ud83d\udcbb APIs for creating interactive CLI tools.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/console.git\n,\n \nfrom\n:\n \n3.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nConsole\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Console\n to access the APIs.\n\n\nOverview\n\n\nContinue to \nConsole \u2192 Overview\n for an overview of Console's features.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/console/getting-started/#getting-started-with-console", 
            "text": "The Console module is provided as a part of Vapor's Console package ( vapor/console ).  This module provides APIs for performing console I/O including things like outputting stylized text, requesting user input, and displaying activity indicators like loading bars.   Tip  For an in-depth look at all of Console's APIs, check out the  Console API docs .", 
            "title": "Getting Started with Console"
        }, 
        {
            "location": "/console/getting-started/#usage", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  Console  APIs when you import  Vapor .  import   Vapor   // implies import Console", 
            "title": "Usage"
        }, 
        {
            "location": "/console/getting-started/#standalone", 
            "text": "The Console module, part of the larger Vapor Console package, can also be used on its own with any Swift project.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         /// \ud83d\udcbb APIs for creating interactive CLI tools. \n         . package ( url :   https://github.com/vapor/console.git ,   from :   3.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Console ,   ...   ]) \n     ]  )   Use  import Console  to access the APIs.", 
            "title": "Standalone"
        }, 
        {
            "location": "/console/getting-started/#overview", 
            "text": "Continue to  Console \u2192 Overview  for an overview of Console's features.", 
            "title": "Overview"
        }, 
        {
            "location": "/console/overview/", 
            "text": "Console Overview\n\n\nThis guide will give you a brief introduction to the Console module, showing you how to output stylized text and request user input.\n\n\nTerminal\n\n\nA default implementation of the \nConsole\n protocol called \nTerminal\n is provided for you to use.\n\n\nlet\n \nterminal\n \n=\n \nTerminal\n()\n\n\nprint\n(\nterminal\n \nis\n \nConsole\n)\n \n// true\n\n\nterminal\n.\nprint\n(\nHello\n)\n\n\n\n\n\n\nThe rest of this guide will assume a generic \nConsole\n, but using \nTerminal\n  directly will also work fine.  You can use any available  \nContainer\n to create a console.\n\n\nlet\n \nconsole\n \n=\n \ntry\n \nreq\n.\nmake\n(\nConsole\n.\nself\n)\n\n\nconsole\n.\nprint\n(\nHello\n)\n\n\n\n\n\n\nOutput\n\n\nConsole\n provides several convenience methods for outputting strings, like \nprint(_:)\n and \nwarning(_:)\n. All of these methods eventually call \noutput(_:)\n which is the most powerful output method. This method accepts \nConsoleText\n which supports independently styled string components.\n\n\n/// Prints \nHello, world\n, but the word \nworld\n is blue.\n\n\nconsole\n.\noutput\n(\nHello, \n \n+\n \nworld\n.\nconsoleText\n(\ncolor\n:\n \n.\nblue\n))\n\n\n\n\n\n\nYou can combine as many differently styled fragments to a \nConsoleText\n as you like. All \nConsole\n methods that output text should have an overload for accepting \nConsoleText\n.\n\n\nInput\n\n\nConsole\n offers several methods for requesting input from the user, the most basic of which is \ninput(isSecure:)\n.\n\n\n/// Accepts input from the terminal until the first newline.\n\n\nlet\n \ninput\n \n=\n \nconsole\n.\ninput\n()\n\n\nconsole\n.\nprint\n(\nYou wrote: \n\\(\ninput\n)\n)\n\n\n\n\n\n\nAsk\n\n\nUse \nask(_:)\n to supply a prompt and input indicator to the user.\n\n\n/// Outputs the prompt then requests input.\n\n\nlet\n \nname\n \n=\n \nconsole\n.\nask\n(\nWhat is your name?\n)\n\n\nconsole\n.\nprint\n(\nYou said: \n\\(\nname\n)\n)\n\n\n\n\n\n\nThe above code will output:\n\n\nWhat is your name?\n\n Vapor\nYou said: Vapor\n\n\n\n\n\nConfirm\n\n\nUse \nconfirm(_:)\n to prompt the user for yes / no input.\n\n\n/// Prompts the user for yes / no input.\n\n\nif\n \nconsole\n.\nconfirm\n(\nAre you sure?\n)\n \n{\n\n    \n// they are sure\n\n\n}\n \nelse\n \n{\n\n    \n// don\nt do it!\n\n\n}\n\n\n\n\n\n\nThe above code will output:\n\n\nAre\n \nyou\n \nsure\n?\n\n\ny\n/\nn\n \nyes\n\n\n\n\n\n\n\n\nNote\n\n\nconfirm(_:)\n will continue to prompt the user until they respond with something recognized as yes or no.", 
            "title": "Overview"
        }, 
        {
            "location": "/console/overview/#console-overview", 
            "text": "This guide will give you a brief introduction to the Console module, showing you how to output stylized text and request user input.", 
            "title": "Console Overview"
        }, 
        {
            "location": "/console/overview/#terminal", 
            "text": "A default implementation of the  Console  protocol called  Terminal  is provided for you to use.  let   terminal   =   Terminal ()  print ( terminal   is   Console )   // true  terminal . print ( Hello )   The rest of this guide will assume a generic  Console , but using  Terminal   directly will also work fine.  You can use any available   Container  to create a console.  let   console   =   try   req . make ( Console . self )  console . print ( Hello )", 
            "title": "Terminal"
        }, 
        {
            "location": "/console/overview/#output", 
            "text": "Console  provides several convenience methods for outputting strings, like  print(_:)  and  warning(_:) . All of these methods eventually call  output(_:)  which is the most powerful output method. This method accepts  ConsoleText  which supports independently styled string components.  /// Prints  Hello, world , but the word  world  is blue.  console . output ( Hello,    +   world . consoleText ( color :   . blue ))   You can combine as many differently styled fragments to a  ConsoleText  as you like. All  Console  methods that output text should have an overload for accepting  ConsoleText .", 
            "title": "Output"
        }, 
        {
            "location": "/console/overview/#input", 
            "text": "Console  offers several methods for requesting input from the user, the most basic of which is  input(isSecure:) .  /// Accepts input from the terminal until the first newline.  let   input   =   console . input ()  console . print ( You wrote:  \\( input ) )", 
            "title": "Input"
        }, 
        {
            "location": "/console/overview/#ask", 
            "text": "Use  ask(_:)  to supply a prompt and input indicator to the user.  /// Outputs the prompt then requests input.  let   name   =   console . ask ( What is your name? )  console . print ( You said:  \\( name ) )   The above code will output:  What is your name?  Vapor\nYou said: Vapor", 
            "title": "Ask"
        }, 
        {
            "location": "/console/overview/#confirm", 
            "text": "Use  confirm(_:)  to prompt the user for yes / no input.  /// Prompts the user for yes / no input.  if   console . confirm ( Are you sure? )   { \n     // they are sure  }   else   { \n     // don t do it!  }   The above code will output:  Are   you   sure ?  y / n   yes    Note  confirm(_:)  will continue to prompt the user until they respond with something recognized as yes or no.", 
            "title": "Confirm"
        }, 
        {
            "location": "/command/getting-started/", 
            "text": "Getting Started with Command\n\n\nThe Command module is provided as a part of Vapor's Console package (\nvapor/console\n).  This module provides APIs for creating command-line interfaces (CLIs). It's what powers the \nVapor Toolbox\n.\n\n\n\n\nTip\n\n\nFor an in-depth look at all of Command's APIs, check out the \nCommand API docs\n.\n\n\n\n\nUsage\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nCommand\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n \n// implies import Command\n\n\n\n\n\n\nStandalone\n\n\nThe Command module, part of the larger Vapor Console package, can also be used on its own with any Swift project.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n/// \ud83d\udcbb APIs for creating interactive CLI tools.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/console.git\n,\n \nfrom\n:\n \n3.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nCommand\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Command\n to access the APIs.\n\n\nOverview\n\n\nContinue to \nCommand \u2192 Overview\n for an overview of Command's features.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/command/getting-started/#getting-started-with-command", 
            "text": "The Command module is provided as a part of Vapor's Console package ( vapor/console ).  This module provides APIs for creating command-line interfaces (CLIs). It's what powers the  Vapor Toolbox .   Tip  For an in-depth look at all of Command's APIs, check out the  Command API docs .", 
            "title": "Getting Started with Command"
        }, 
        {
            "location": "/command/getting-started/#usage", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  Command  APIs when you import  Vapor .  import   Vapor   // implies import Command", 
            "title": "Usage"
        }, 
        {
            "location": "/command/getting-started/#standalone", 
            "text": "The Command module, part of the larger Vapor Console package, can also be used on its own with any Swift project.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         /// \ud83d\udcbb APIs for creating interactive CLI tools. \n         . package ( url :   https://github.com/vapor/console.git ,   from :   3.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Command ,   ...   ]) \n     ]  )   Use  import Command  to access the APIs.", 
            "title": "Standalone"
        }, 
        {
            "location": "/command/getting-started/#overview", 
            "text": "Continue to  Command \u2192 Overview  for an overview of Command's features.", 
            "title": "Overview"
        }, 
        {
            "location": "/command/overview/", 
            "text": "Command Overview\n\n\nThis guide will introduce you to the Command module by showing you how to create your own CLI. For this example, we will implement \ncowsay\n, a command that prints an ASCII picture of a cow with a message.\n\n\n\n\nTip\n\n\nYou can install the real \ncowsay\n program using \nbrew install cowsay\n.\n\n\n\n\n$ cowsay Hello\n  -----\n\n Hello \n\n  -----\n          \n\\ \n  ^__^\n           \n\\ \n \n(\noo\n\\_\n______\n              \n(\n__\n)\n\\ \n      \n)\n\\/\\\n\n                   \n||\n----w \n|\n\n                   \n||\n     \n||\n\n\n\n\n\n\nCommand\n\n\nThe first step is to create a type that conforms to \nCommand\n.\n\n\n/// Generates ASCII picture of a cow with a message.\n\n\nstruct\n \nCowsayCommand\n:\n \nCommand\n \n{\n\n    \n...\n\n\n}\n\n\n\n\n\n\nNow let's implement the required methods.\n\n\nArguments\n\n\nCommands can have zero or more \nCommandArgument\ns. These arguments will be required for the command to run.\n\n\n/// Generates ASCII picture of a cow with a message.\n\n\nstruct\n \nCowsayCommand\n:\n \nCommand\n \n{\n\n    \n/// See `Command`\n\n    \nvar\n \narguments\n:\n \n[\nCommandArgument\n]\n \n{\n\n        \nreturn\n \n[.\nargument\n(\nname\n:\n \nmessage\n)]\n\n    \n}\n\n\n    \n...\n\n\n}\n\n\n\n\n\n\nHere we are defining one argument, the \nmessage\n that the cow will say. This is required to run the \ncowsay\n command.\n\n\nOptions\n\n\nCommands can have zero or more \nCommandOption\ns. These options are not required for the command to run and can be passed using \n--\n or \n-\n syntax.\n\n\n/// Generates ASCII picture of a cow with a message.\n\n\nstruct\n \nCowsayCommand\n:\n \nCommand\n \n{\n\n    \n...\n\n    \n/// See `Command`\n\n    \nvar\n \noptions\n:\n \n[\nCommandOption\n]\n \n{\n\n        \nreturn\n \n[\n\n            \n.\nvalue\n(\nname\n:\n \neyes\n,\n \nshort\n:\n \ne\n,\n \ndefault\n:\n \noo\n,\n \nhelp\n:\n \n[\nChange cow\ns eyes\n]),\n\n            \n.\nvalue\n(\nname\n:\n \ntongue\n,\n \nshort\n:\n \nt\n,\n \ndefault\n:\n \n \n,\n \nhelp\n:\n \n[\nChange cow\ns tongue\n]),\n\n        \n]\n\n    \n}\n\n    \n...\n\n\n}\n\n\n\n\n\n\nHere we are defining two options, \neyes\n and \ntongue\n. These will let the user optionally change how the cow looks.\n\n\nHelp\n\n\nNext we can define an optional help message to display when the user passes \n--help\n.\n\n\n/// Generates ASCII picture of a cow with a message.\n\n\nstruct\n \nCowsayCommand\n:\n \nCommand\n \n{\n\n    \n...\n\n    \n/// See `Command`\n\n    \nvar\n \nhelp\n:\n \n[\nString\n]\n \n{\n\n        \nreturn\n \n[\nGenerates ASCII picture of a cow with a message.\n]\n\n    \n}\n\n    \n...\n\n\n}\n\n\n\n\n\n\nLet's take a look at how this will look once our command is complete:\n\n\nUsage: \nexecutable\n cowsay \nmessage\n \n[\n--eyes,-e\n]\n \n[\n--tongue,-t\n]\n \n\nGenerates ASCII picture of a cow with a message.\n\nArguments:\n  message n/a\n\nOptions:\n     eyes Change cow\ns eyes\n\n\n   tongue Change cow\ns tongue\n\n\n\n\n\nRun\n\n\nFinally, we need to write our implementation:\n\n\n/// Generates ASCII picture of a cow with a message.\n\n\nstruct\n \nCowsayCommand\n:\n \nCommand\n \n{\n\n    \n...\n\n\n    \n/// See `Command`.\n\n    \nfunc\n \nrun\n(\nusing\n \ncontext\n:\n \nCommandContext\n)\n \nthrows\n \n-\n \nFuture\n \n{\n\n        \nlet\n \nmessage\n \n=\n \ntry\n \ncontext\n.\nargument\n(\nmessage\n)\n\n        \n/// We can use requireOption here since both options have default values\n\n        \nlet\n \neyes\n \n=\n \ntry\n \ncontext\n.\nrequireOption\n(\neyes\n)\n\n        \nlet\n \ntongue\n \n=\n \ntry\n \ncontext\n.\nrequireOption\n(\ntongue\n)\n\n        \nlet\n \npadding\n \n=\n \nString\n(\nrepeating\n:\n \n-\n,\n \ncount\n:\n \nmessage\n.\ncount\n)\n\n        \nlet\n \ntext\n:\n \nString\n \n=\n \n\n\n          \n\\(\npadding\n)\n\n\n        \n \n\\(\nmessage\n)\n \n\n\n          \n\\(\npadding\n)\n\n\n                  \n\\\\\n   ^__^\n\n\n                   \n\\\\\n  (\n\\(\neyes\n)\n\\\\\n_______\n\n\n                      (__)\n\\\\\n       )\n\\\\\n/\n\\\\\n\n\n                        \n\\(\ntongue\n)\n  ||----w |\n\n\n                           ||     ||\n\n\n        \n\n        \ncontext\n.\nconsole\n.\nprint\n(\ntext\n)\n\n        \nreturn\n \n.\ndone\n(\non\n:\n \ncontext\n.\ncontainer\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nThe \nCommandContext\n gives you access to everything you will need, including a \nContainer\n. Now that we have a complete \nCommand\n, the next step is to configure it.\n\n\nConfig\n\n\nUse the \nCommandConfig\n struct to register commands to your container. This is usually done in \nconfigure.swift\n\n\n/// Create a `CommandConfig` with default commands.\n\n\nvar\n \ncommandConfig\n \n=\n \nCommandConfig\n.\ndefault\n()\n\n\n/// Add the `CowsayCommand`.\n\n\ncommandConfig\n.\nuse\n(\nCowsayCommand\n(),\n \nas\n:\n \ncowsay\n)\n\n\n/// Register this `CommandConfig` to services.\n\n\nservices\n.\nregister\n(\ncommandConfig\n)\n\n\n\n\n\n\nCheck that your command was properly configured using \n--help\n.\n\n\nswift\n \nrun\n \nRun\n \ncowsay\n \n--\nhelp\n\n\n\n\n\n\nThat's it!\n\n\n$\n \nswift\n \nrun\n \nRun\n \ncowsay\n \nGood\n \njob\n!\n \n-\ne\n \n^^\n \n-\nt\n \nU\n\n  \n---------\n\n\n \nGood\n \njob\n!\n \n\n  \n---------\n\n          \n\\\n   \n^\n__\n^\n\n           \n\\\n  \n(\n^^\n\\\n_______\n\n              \n(\n__\n)\n\\\n       \n)\n\\\n/\n\\\n\n                \nU\n  \n||----\nw\n \n|\n\n                   \n||\n     \n||", 
            "title": "Overview"
        }, 
        {
            "location": "/command/overview/#command-overview", 
            "text": "This guide will introduce you to the Command module by showing you how to create your own CLI. For this example, we will implement  cowsay , a command that prints an ASCII picture of a cow with a message.   Tip  You can install the real  cowsay  program using  brew install cowsay .   $ cowsay Hello\n  -----  Hello  \n  -----\n           \\    ^__^\n            \\    ( oo \\_ ______\n               ( __ ) \\         ) \\/\\ \n                    || ----w  | \n                    ||       ||", 
            "title": "Command Overview"
        }, 
        {
            "location": "/command/overview/#command", 
            "text": "The first step is to create a type that conforms to  Command .  /// Generates ASCII picture of a cow with a message.  struct   CowsayCommand :   Command   { \n     ...  }   Now let's implement the required methods.", 
            "title": "Command"
        }, 
        {
            "location": "/command/overview/#arguments", 
            "text": "Commands can have zero or more  CommandArgument s. These arguments will be required for the command to run.  /// Generates ASCII picture of a cow with a message.  struct   CowsayCommand :   Command   { \n     /// See `Command` \n     var   arguments :   [ CommandArgument ]   { \n         return   [. argument ( name :   message )] \n     } \n\n     ...  }   Here we are defining one argument, the  message  that the cow will say. This is required to run the  cowsay  command.", 
            "title": "Arguments"
        }, 
        {
            "location": "/command/overview/#options", 
            "text": "Commands can have zero or more  CommandOption s. These options are not required for the command to run and can be passed using  --  or  -  syntax.  /// Generates ASCII picture of a cow with a message.  struct   CowsayCommand :   Command   { \n     ... \n     /// See `Command` \n     var   options :   [ CommandOption ]   { \n         return   [ \n             . value ( name :   eyes ,   short :   e ,   default :   oo ,   help :   [ Change cow s eyes ]), \n             . value ( name :   tongue ,   short :   t ,   default :     ,   help :   [ Change cow s tongue ]), \n         ] \n     } \n     ...  }   Here we are defining two options,  eyes  and  tongue . These will let the user optionally change how the cow looks.", 
            "title": "Options"
        }, 
        {
            "location": "/command/overview/#help", 
            "text": "Next we can define an optional help message to display when the user passes  --help .  /// Generates ASCII picture of a cow with a message.  struct   CowsayCommand :   Command   { \n     ... \n     /// See `Command` \n     var   help :   [ String ]   { \n         return   [ Generates ASCII picture of a cow with a message. ] \n     } \n     ...  }   Let's take a look at how this will look once our command is complete:  Usage:  executable  cowsay  message   [ --eyes,-e ]   [ --tongue,-t ]  \n\nGenerates ASCII picture of a cow with a message.\n\nArguments:\n  message n/a\n\nOptions:\n     eyes Change cow s eyes     tongue Change cow s tongue", 
            "title": "Help"
        }, 
        {
            "location": "/command/overview/#run", 
            "text": "Finally, we need to write our implementation:  /// Generates ASCII picture of a cow with a message.  struct   CowsayCommand :   Command   { \n     ... \n\n     /// See `Command`. \n     func   run ( using   context :   CommandContext )   throws   -   Future   { \n         let   message   =   try   context . argument ( message ) \n         /// We can use requireOption here since both options have default values \n         let   eyes   =   try   context . requireOption ( eyes ) \n         let   tongue   =   try   context . requireOption ( tongue ) \n         let   padding   =   String ( repeating :   - ,   count :   message . count ) \n         let   text :   String   =               \\( padding )             \\( message )               \\( padding )                     \\\\    ^__^                      \\\\   ( \\( eyes ) \\\\ _______                        (__) \\\\        ) \\\\ / \\\\                           \\( tongue )   ||----w |                             ||     ||           \n         context . console . print ( text ) \n         return   . done ( on :   context . container ) \n     }  }   The  CommandContext  gives you access to everything you will need, including a  Container . Now that we have a complete  Command , the next step is to configure it.", 
            "title": "Run"
        }, 
        {
            "location": "/command/overview/#config", 
            "text": "Use the  CommandConfig  struct to register commands to your container. This is usually done in  configure.swift  /// Create a `CommandConfig` with default commands.  var   commandConfig   =   CommandConfig . default ()  /// Add the `CowsayCommand`.  commandConfig . use ( CowsayCommand (),   as :   cowsay )  /// Register this `CommandConfig` to services.  services . register ( commandConfig )   Check that your command was properly configured using  --help .  swift   run   Run   cowsay   -- help   That's it!  $   swift   run   Run   cowsay   Good   job !   - e   ^^   - t   U \n   ---------    Good   job !   \n   --------- \n           \\     ^ __ ^ \n            \\    ( ^^ \\ _______ \n               ( __ ) \\         ) \\ / \\ \n                 U    ||---- w   | \n                    ||       ||", 
            "title": "Config"
        }, 
        {
            "location": "/core/getting-started/", 
            "text": "Getting Started with Async\n\n\nComing soon.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/core/getting-started/#getting-started-with-async", 
            "text": "Coming soon.", 
            "title": "Getting Started with Async"
        }, 
        {
            "location": "/core/overview/", 
            "text": "Async Overview\n\n\nComing soon.", 
            "title": "Overview"
        }, 
        {
            "location": "/core/overview/#async-overview", 
            "text": "Coming soon.", 
            "title": "Async Overview"
        }, 
        {
            "location": "/crypto/getting-started/", 
            "text": "Using Crypto\n\n\nCrypto (\nvapor/crypto\n) is a library containing common APIs related to cryptography and data generation. The package contains two modules:\n\n\n\n\nCrypto\n\n\nRandom\n\n\n\n\nWith Vapor\n\n\nThis package is included with Vapor by default, just add:\n\n\nimport\n \nCrypto\n\n\nimport\n \nRandom\n\n\n\n\n\n\nWithout Vapor\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/crypto.git\n,\n \n.\nupToNextMajor\n(\nfrom\n:\n \nx.0.0\n)),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nCrypto\n,\n \nRandom\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Crypto\n to access Crypto's APIs and \nimport Random\n to access Random's APIs.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/crypto/getting-started/#using-crypto", 
            "text": "Crypto ( vapor/crypto ) is a library containing common APIs related to cryptography and data generation. The package contains two modules:   Crypto  Random", 
            "title": "Using Crypto"
        }, 
        {
            "location": "/crypto/getting-started/#with-vapor", 
            "text": "This package is included with Vapor by default, just add:  import   Crypto  import   Random", 
            "title": "With Vapor"
        }, 
        {
            "location": "/crypto/getting-started/#without-vapor", 
            "text": "To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/crypto.git ,   . upToNextMajor ( from :   x.0.0 )), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Crypto ,   Random ,   ...   ]) \n     ]  )   Use  import Crypto  to access Crypto's APIs and  import Random  to access Random's APIs.", 
            "title": "Without Vapor"
        }, 
        {
            "location": "/crypto/digests/", 
            "text": "Message Digests\n\n\nCryptographic hash functions (also known as message digest algorithms) convert data of arbitrary size to a fixed-size digest. These are most often used for generating checksums or identifiers for large data blobs.\n\n\nRead more about \nCryptographic hash functions\n on Wikipedia.\n\n\nHash\n\n\nUse the global convenience variables to create hashes using common algorithms.\n\n\nimport\n \nCrypto\n\n\n\nlet\n \ndigest\n \n=\n \ntry\n \nSHA1\n.\nhash\n(\nhello\n)\n\n\nprint\n(\ndigest\n.\nhexEncodedString\n())\n \n// aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d\n\n\n\n\n\n\nSee the Crypto module's \nglobal variables\n for a list of all available hash algorithms.\n\n\nStreaming\n\n\nYou can create a \nDigest\n manually and use its instance methods to create a hash for one or more data chunks.\n\n\nvar\n \nsha256\n \n=\n \ntry\n \nDigest\n(\nalgorithm\n:\n \n.\nsha256\n)\n\n\ntry\n \nsha256\n.\nreset\n()\n\n\ntry\n \nsha256\n.\nupdate\n(\ndata\n:\n \nhello\n)\n\n\ntry\n \nsha256\n.\nupdate\n(\ndata\n:\n \nworld\n)\n\n\nlet\n \ndigest\n \n=\n \ntry\n \nsha256\n.\nfinish\n()\n\n\nprint\n(\ndigest\n)\n \n/// Data\n\n\n\n\n\n\nBCrypt\n\n\nBCrypt is a popular hashing algorithm that has configurable complexity and handles salting automatically.\n\n\nHash\n\n\nUse the \nhash(_:cost:salt:)\n method to create BCrypt hashes.\n\n\nlet\n \ndigest\n \n=\n \ntry\n \nBCrypt\n.\nhash\n(\nvapor\n,\n \ncost\n:\n \n4\n)\n\n\nprint\n(\ndigest\n)\n \n/// data\n\n\n\n\n\n\nIncreasing the \ncost\n value will make hashing and verification take longer.\n\n\nVerify\n\n\nUse the \nverify(_:created:)\n method to verify that a BCrypt hash was created by a given plaintext input.\n\n\nlet\n \nhash\n \n=\n \ntry\n \nBCrypt\n.\nhash\n(\nvapor\n,\n \ncost\n:\n \n4\n)\n\n\ntry\n \nBCrypt\n.\nverify\n(\nvapor\n,\n \ncreated\n:\n \nhash\n)\n \n// true\n\n\ntry\n \nBCrypt\n.\nverify\n(\nfoo\n,\n \ncreated\n:\n \nhash\n)\n \n// false\n\n\n\n\n\n\nHMAC\n\n\nHMAC is an algorithm for creating \nkeyed\n hashes. HMAC will generate different hashes for the same input if different keys are used.\n\n\nlet\n \ndigest\n \n=\n \ntry\n \nHMAC\n.\nSHA1\n.\nauthenticate\n(\nvapor\n,\n \nkey\n:\n \nsecret\n)\n \n\nprint\n(\ndigest\n.\nhexEncodedString\n())\n \n// digest\n\n\n\n\n\n\nSee the \nHMAC\n class for a list of all available hash algorithms.\n\n\nStreaming\n\n\nHMAC hashes can also be streamed. The API is identical to \nhash streaming\n.", 
            "title": "Digests"
        }, 
        {
            "location": "/crypto/digests/#message-digests", 
            "text": "Cryptographic hash functions (also known as message digest algorithms) convert data of arbitrary size to a fixed-size digest. These are most often used for generating checksums or identifiers for large data blobs.  Read more about  Cryptographic hash functions  on Wikipedia.", 
            "title": "Message Digests"
        }, 
        {
            "location": "/crypto/digests/#hash", 
            "text": "Use the global convenience variables to create hashes using common algorithms.  import   Crypto  let   digest   =   try   SHA1 . hash ( hello )  print ( digest . hexEncodedString ())   // aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d   See the Crypto module's  global variables  for a list of all available hash algorithms.", 
            "title": "Hash"
        }, 
        {
            "location": "/crypto/digests/#streaming", 
            "text": "You can create a  Digest  manually and use its instance methods to create a hash for one or more data chunks.  var   sha256   =   try   Digest ( algorithm :   . sha256 )  try   sha256 . reset ()  try   sha256 . update ( data :   hello )  try   sha256 . update ( data :   world )  let   digest   =   try   sha256 . finish ()  print ( digest )   /// Data", 
            "title": "Streaming"
        }, 
        {
            "location": "/crypto/digests/#bcrypt", 
            "text": "BCrypt is a popular hashing algorithm that has configurable complexity and handles salting automatically.", 
            "title": "BCrypt"
        }, 
        {
            "location": "/crypto/digests/#hash_1", 
            "text": "Use the  hash(_:cost:salt:)  method to create BCrypt hashes.  let   digest   =   try   BCrypt . hash ( vapor ,   cost :   4 )  print ( digest )   /// data   Increasing the  cost  value will make hashing and verification take longer.", 
            "title": "Hash"
        }, 
        {
            "location": "/crypto/digests/#verify", 
            "text": "Use the  verify(_:created:)  method to verify that a BCrypt hash was created by a given plaintext input.  let   hash   =   try   BCrypt . hash ( vapor ,   cost :   4 )  try   BCrypt . verify ( vapor ,   created :   hash )   // true  try   BCrypt . verify ( foo ,   created :   hash )   // false", 
            "title": "Verify"
        }, 
        {
            "location": "/crypto/digests/#hmac", 
            "text": "HMAC is an algorithm for creating  keyed  hashes. HMAC will generate different hashes for the same input if different keys are used.  let   digest   =   try   HMAC . SHA1 . authenticate ( vapor ,   key :   secret )   print ( digest . hexEncodedString ())   // digest   See the  HMAC  class for a list of all available hash algorithms.", 
            "title": "HMAC"
        }, 
        {
            "location": "/crypto/digests/#streaming_1", 
            "text": "HMAC hashes can also be streamed. The API is identical to  hash streaming .", 
            "title": "Streaming"
        }, 
        {
            "location": "/crypto/ciphers/", 
            "text": "Cipher Algorithms\n\n\nCiphers allow you to encrypt plaintext data with a key yielding ciphertext. This ciphertext can be later decrypted by the same cipher using the same key.\n\n\nRead more about \nciphers\n on Wikipedia.\n\n\nEncrypt\n\n\nUse the global convenience variables for encrypting data with common algorithms.\n\n\nlet\n \nciphertext\n \n=\n \ntry\n \nAES128\n.\nencrypt\n(\nvapor\n,\n \nkey\n:\n \nsecret\n)\n\n\nprint\n(\nciphertext\n)\n \n/// Data\n\n\n\n\n\n\nDecrypt\n\n\nDecryption works very similarly to \nencryption\n. The following snippet shows how to decrypt the ciphertext from our previous example.\n\n\nlet\n \nplaintext\n \n=\n \ntry\n \nAES128\n.\ndecrypt\n(\nciphertext\n,\n \nkey\n:\n \nsecret\n)\n\n\nprint\n(\nplaintext\n)\n \n/// \nvapor\n\n\n\n\n\n\nSee the Crypto module's \nglobal variables\n for a list of all available cipher algorithms.\n\n\nStreaming\n\n\nBoth encryption and decryption can work in a streaming mode that allows data to be chunked. This is useful for controlling memory usage while encrypting large amounts of data.\n\n\nlet\n \nkey\n:\n \nData\n \n// 16-bytes\n\n\nlet\n \naes128\n \n=\n \nCipher\n(\nalgorithm\n:\n \n.\naes128ecb\n)\n\n\ntry\n \naes128\n.\nreset\n(\nkey\n:\n \nkey\n,\n \nmode\n:\n \n.\nencrypt\n)\n\n\nvar\n \nbuffer\n \n=\n \nData\n()\n\n\ntry\n \naes128\n.\nupdate\n(\ndata\n:\n \nhello\n,\n \ninto\n:\n \nbuffer\n)\n\n\ntry\n \naes128\n.\nupdate\n(\ndata\n:\n \nworld\n,\n \ninto\n:\n \nbuffer\n)\n\n\ntry\n \naes128\n.\nfinish\n(\ninto\n:\n \nbuffer\n)\n\n\nprint\n(\nbuffer\n)\n \n// Completed ciphertext", 
            "title": "Ciphers"
        }, 
        {
            "location": "/crypto/ciphers/#cipher-algorithms", 
            "text": "Ciphers allow you to encrypt plaintext data with a key yielding ciphertext. This ciphertext can be later decrypted by the same cipher using the same key.  Read more about  ciphers  on Wikipedia.", 
            "title": "Cipher Algorithms"
        }, 
        {
            "location": "/crypto/ciphers/#encrypt", 
            "text": "Use the global convenience variables for encrypting data with common algorithms.  let   ciphertext   =   try   AES128 . encrypt ( vapor ,   key :   secret )  print ( ciphertext )   /// Data", 
            "title": "Encrypt"
        }, 
        {
            "location": "/crypto/ciphers/#decrypt", 
            "text": "Decryption works very similarly to  encryption . The following snippet shows how to decrypt the ciphertext from our previous example.  let   plaintext   =   try   AES128 . decrypt ( ciphertext ,   key :   secret )  print ( plaintext )   ///  vapor   See the Crypto module's  global variables  for a list of all available cipher algorithms.", 
            "title": "Decrypt"
        }, 
        {
            "location": "/crypto/ciphers/#streaming", 
            "text": "Both encryption and decryption can work in a streaming mode that allows data to be chunked. This is useful for controlling memory usage while encrypting large amounts of data.  let   key :   Data   // 16-bytes  let   aes128   =   Cipher ( algorithm :   . aes128ecb )  try   aes128 . reset ( key :   key ,   mode :   . encrypt )  var   buffer   =   Data ()  try   aes128 . update ( data :   hello ,   into :   buffer )  try   aes128 . update ( data :   world ,   into :   buffer )  try   aes128 . finish ( into :   buffer )  print ( buffer )   // Completed ciphertext", 
            "title": "Streaming"
        }, 
        {
            "location": "/crypto/asymmetric/", 
            "text": "Asymmetric Cryptography\n\n\nAsymmetric cryptography (also called public-key cryptography) is a cryptographic system that uses multiple keys\nusually a \"public\" and \"private\" key.\n\n\nRead more about \npublic-key cryptography\n on Wikipedia.\n\n\nRSA\n\n\nA popular asymmetric cryptography algorithm is RSA. RSA has two key types: public and private.\n\n\nRSA can create signatures from any data using a private key. \n\n\nlet\n \nprivateKey\n:\n \nString\n \n=\n \n...\n\n\nlet\n \nsignature\n \n=\n \ntry\n \nRSA\n.\nSHA512\n.\nsign\n(\nvapor\n,\n \nkey\n:\n \n.\nprivate\n(\npem\n:\n \nprivateKey\n))\n\n\n\n\n\n\n\n\nInfo\n\n\nOnly private keys can \ncreate\n signatures.\n\n\n\n\nThese signatures can be verified against the same data later using either the public or private key.\n\n\nlet\n \npublicKey\n:\n \nString\n \n=\n \n...\n\n\ntry\n \nRSA\n.\nSHA512\n.\nverify\n(\nsignature\n,\n \nsigns\n:\n \nvapor\n,\n \nkey\n:\n \n.\npublic\n(\npem\n:\n \npublicKey\n))\n \n// true\n\n\n\n\n\n\nIf RSA verifies that a signature matches input data for a public key, you can be sure that whoever generated that signature had access to that key's private key.\n\n\nAlgorithms\n\n\nRSA supports any of the Crypto module's \nDigestAlgorithm\n.\n\n\nlet\n \nprivateKey\n:\n \nString\n \n=\n \n...\n\n\nlet\n \nsignature512\n \n=\n \ntry\n \nRSA\n.\nSHA512\n.\nsign\n(\nvapor\n,\n \nkey\n:\n \n.\nprivate\n(\npem\n:\n \nprivateKey\n))\n\n\nlet\n \nsignature256\n \n=\n \ntry\n \nRSA\n.\nSHA256\n.\nsign\n(\nvapor\n,\n \nkey\n:\n \n.\nprivate\n(\npem\n:\n \nprivateKey\n))", 
            "title": "Asymmetric"
        }, 
        {
            "location": "/crypto/asymmetric/#asymmetric-cryptography", 
            "text": "Asymmetric cryptography (also called public-key cryptography) is a cryptographic system that uses multiple keys usually a \"public\" and \"private\" key.  Read more about  public-key cryptography  on Wikipedia.", 
            "title": "Asymmetric Cryptography"
        }, 
        {
            "location": "/crypto/asymmetric/#rsa", 
            "text": "A popular asymmetric cryptography algorithm is RSA. RSA has two key types: public and private.  RSA can create signatures from any data using a private key.   let   privateKey :   String   =   ...  let   signature   =   try   RSA . SHA512 . sign ( vapor ,   key :   . private ( pem :   privateKey ))    Info  Only private keys can  create  signatures.   These signatures can be verified against the same data later using either the public or private key.  let   publicKey :   String   =   ...  try   RSA . SHA512 . verify ( signature ,   signs :   vapor ,   key :   . public ( pem :   publicKey ))   // true   If RSA verifies that a signature matches input data for a public key, you can be sure that whoever generated that signature had access to that key's private key.", 
            "title": "RSA"
        }, 
        {
            "location": "/crypto/asymmetric/#algorithms", 
            "text": "RSA supports any of the Crypto module's  DigestAlgorithm .  let   privateKey :   String   =   ...  let   signature512   =   try   RSA . SHA512 . sign ( vapor ,   key :   . private ( pem :   privateKey ))  let   signature256   =   try   RSA . SHA256 . sign ( vapor ,   key :   . private ( pem :   privateKey ))", 
            "title": "Algorithms"
        }, 
        {
            "location": "/crypto/random/", 
            "text": "Random\n\n\nThe \nRandom\n module deals with random data generation including random number generation.\n\n\nData Generator\n\n\nThe \nDataGenerator\n class powers all of the random data generators.\n\n\nImplementations\n\n\n\n\n\n\nOSRandom\n: Provides a random data generator using a platform-specific method.\n\n\n\n\n\n\nURandom\n provides random data generation based on the \n/dev/urandom\n file.\n\n\n\n\n\n\nCryptoRandom\n from the \nCrypto\n module provides cryptographically-secure random data using OpenSSL.\n\n\n\n\n\n\nlet\n \nrandom\n:\n \nDataGenerator\n \n...\n\n\nlet\n \ndata\n \n=\n \ntry\n \nrandom\n.\ngenerateData\n(\nbytes\n:\n \n8\n)\n\n\n\n\n\n\nGenerate\n\n\nDataGenerator\ns are capable of generating random primitive types using the \ngenerate(_:)\n method.\n\n\nlet\n \nint\n \n=\n \ntry\n \nOSRandom\n().\ngenerate\n(\nInt\n.\nself\n)\n\n\nprint\n(\nint\n)\n \n// Int", 
            "title": "Random"
        }, 
        {
            "location": "/crypto/random/#random", 
            "text": "The  Random  module deals with random data generation including random number generation.", 
            "title": "Random"
        }, 
        {
            "location": "/crypto/random/#data-generator", 
            "text": "The  DataGenerator  class powers all of the random data generators.", 
            "title": "Data Generator"
        }, 
        {
            "location": "/crypto/random/#implementations", 
            "text": "OSRandom : Provides a random data generator using a platform-specific method.    URandom  provides random data generation based on the  /dev/urandom  file.    CryptoRandom  from the  Crypto  module provides cryptographically-secure random data using OpenSSL.    let   random :   DataGenerator   ...  let   data   =   try   random . generateData ( bytes :   8 )", 
            "title": "Implementations"
        }, 
        {
            "location": "/crypto/random/#generate", 
            "text": "DataGenerator s are capable of generating random primitive types using the  generate(_:)  method.  let   int   =   try   OSRandom (). generate ( Int . self )  print ( int )   // Int", 
            "title": "Generate"
        }, 
        {
            "location": "/database-kit/getting-started/", 
            "text": "Getting Started with Database Kit\n\n\nDatabase Kit (\nvapor/database-kit\n) is a framework for configuring and working with database connections. It includes core services like caching, logging, and connection pooling.\n\n\n\n\nTip\n\n\nIf you use Fluent, you will usually not need to use Database Kit manually. \nBut learning the APIs may come in handy.\n\n\n\n\nPackage\n\n\nThe Database Kit package is lightweight, pure Swift, and has few dependencies. This means it can be used as a core database framework for any Swift project\u2014even one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/database-kit.git\n,\n \nfrom\n:\n \n1.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nDatabaseKit\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport DatabaseKit\n to access the APIs.\n\n\nAPI Docs\n\n\nThe rest of this guide will give you an overview of what is available in the DatabaseKit package. As always, feel free to visit the \nAPI docs\n for more in-depth information.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/database-kit/getting-started/#getting-started-with-database-kit", 
            "text": "Database Kit ( vapor/database-kit ) is a framework for configuring and working with database connections. It includes core services like caching, logging, and connection pooling.   Tip  If you use Fluent, you will usually not need to use Database Kit manually. \nBut learning the APIs may come in handy.", 
            "title": "Getting Started with Database Kit"
        }, 
        {
            "location": "/database-kit/getting-started/#package", 
            "text": "The Database Kit package is lightweight, pure Swift, and has few dependencies. This means it can be used as a core database framework for any Swift project\u2014even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/database-kit.git ,   from :   1.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ DatabaseKit ,   ...   ]) \n     ]  )   Use  import DatabaseKit  to access the APIs.", 
            "title": "Package"
        }, 
        {
            "location": "/database-kit/getting-started/#api-docs", 
            "text": "The rest of this guide will give you an overview of what is available in the DatabaseKit package. As always, feel free to visit the  API docs  for more in-depth information.", 
            "title": "API Docs"
        }, 
        {
            "location": "/database-kit/overview/", 
            "text": "Using Database Kit\n\n\nDatabase Kit is a framework for configuring and working with database connections. It helps you do things like manage and pool connections, create keyed caches, and log queries. \n\n\nMany of Vapor's packages such as the Fluent drivers, Redis, and Vapor core are built on top of Database Kit. This guide will walk you through some of the common APIs you might encounter when using Database Kit.\n\n\nConfig\n\n\nYour first interaction with Database Kit will most likely be with the \nDatabasesConfig\n struct. This type helps you configure one or more databases to your application and will ultimately yield a \nDatabases\n struct. This usually takes place in \nconfigure.swift\n.\n\n\n// Create a SQLite database.\n\n\nlet\n \nsqliteDB\n \n=\n \nSQLiteDatabase\n(...)\n\n\n\n// Create a new, empty DatabasesConfig.\n\n\nvar\n \ndbsConfig\n \n=\n \nDatabasesConfig\n()\n\n\n\n// Register the SQLite database using \n.sqlite\n as an identifier.\n\n\ndbsConfig\n.\nadd\n(\nsqliteDB\n,\n \nas\n:\n \n.\nsqlite\n)\n\n\n\n// Register more DBs here if you want\n\n\n\n// Register the DatabaseConfig to services.\n\n\nservices\n.\nregister\n(\ndbsConfig\n)\n\n\n\n\n\n\nUsing the \nadd(...)\n methods, you can register \nDatabase\ns to the config. You can register instances of a database, a database type, or a closure that creates a database. The latter two methods will be resolved when your container boots.\n\n\nYou can also configure options on your databases, such as enabling logging.\n\n\n// Enable logging on the SQLite database\n\n\ndbsConfig\n.\nenableLogging\n(\nfor\n:\n \n.\nsqlite\n)\n\n\n\n\n\n\nSee the section on \nlogging\n for more information.\n\n\nIdentifier\n\n\nMost database integrations will provide a default \nDatabaseIdentifier\n to use. However, you can always create your own. This is usually done by creating a static extension.\n\n\nextension\n \nDatabaseIdentifier\n \n{\n\n    \n/// Test database.\n\n    \nstatic\n \nvar\n \ntesting\n:\n \nDatabaseIdentifier\nMySQLDatabase\n \n{\n\n        \nreturn\n \ntesting\n\n    \n}\n\n\n}\n\n\n\n\n\n\nDatabaseIdentifier\n is \nExpressibleByStringLiteral\n which allows you to create one with just a \nString\n.\n\n\nDatabases\n\n\nOnce you have registered a \nDatabasesConfig\n to your services and booted a container, you can take advantage of the convenience extensions on \nContainer\n to start creating connections.\n\n\n// Creates a new connection to `.sqlite` db\n\n\napp\n.\nwithNewConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nquery\n(...)\n \n// do some db query\n\n\n}\n\n\n\n\n\n\nRead more about creating and managing connections in the next section.\n\n\nConnections\n\n\nDatabase Kit's main focus is on creating, managing, and pooling connections. Creating new connections takes a non-trivial amount of time for your application and many cloud services limit the total number of connections to a service that can be open. Because of this, it is important for high-concurrency web applications to manage their connections carefully.\n\n\nPools\n\n\nA common solution to connection management is the use of connection pools. These pools usually have a set maximum number of connections that are allowed to be open at once. Each time the pool is asked for a connection, it will first check if one is available before creating a new connection. If none are available, it will create a new one. If no connections are available and the pool is already at its maximum, the request for a new connection will \nwait\n for a connection to be returned. \n\n\nThe easiest way to request and release a pooled connection is the method \nwithPooledConnection(...)\n. \n\n\n// Requests a pooled connection to `.psql` db\n\n\nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\npsql\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nquery\n(...)\n \n// do some db query\n\n\n}\n\n\n\n\n\n\nThis method will requested a pooled connection to the identified database and call the provided closure when the connection is available. When the \nFuture\n returned by the closure has completed, the connection will automatically be returned to the pool.\n\n\nIf you need access to a connection outside of a closure, you can use the related request / release methods instead.\n\n\n// Request a connection from the pool and wait for it to be ready.\n\n\nlet\n \nconn\n \n=\n \ntry\n \napp\n.\nrequestPooledConnection\n(\nto\n:\n \n.\npsql\n).\nwait\n()\n\n\n\n// Ensure the connection is released when we exit this scope.\n\n\ndefer\n \n{\n \napp\n.\nreleasePooledConnection\n(\nconn\n,\n \nto\n:\n \n.\npsql\n)\n \n}\n\n\n\n\n\n\nYou can configure your connection pools using the \nDatabaseConnectionPoolConfig\n struct. \n\n\n// Create a new, empty pool config.\n\n\nvar\n \npoolConfig\n \n=\n \nDatabaseConnectionPoolConfig\n()\n\n\n\n// Set max connections per pool to 8.\n\n\npoolConfig\n.\nmaxConnections\n \n=\n \n8\n\n\n\n// Register the pool config.\n\n\nservices\n.\nregister\n(\npoolConfig\n)\n\n\n\n\n\n\nTo prevent race conditions, pools are never shared between event loops. There is usually one pool per database per event loop. This means that the amount of connections your application can potentially open to a given database is equal to \nnumThreads * maxConns\n.\n\n\nNew\n\n\nYou can always create a new connection to your databases if you need to. This will not affect your pooled connections. Creating new connections is especially useful during testing and app boot. But try not to do it in route closures since heavy traffic to your app could end up creating a lot of connections!\n\n\nSimilar to pooled connections, opening and closing new connections can be done using \nwithNewConnection(...)\n. \n\n\n// Creates a new connection to `.sqlite` db\n\n\napp\n.\nwithNewConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nquery\n(...)\n \n// do some db query\n\n\n}\n\n\n\n\n\n\nThis method will create a new connection, calling the supplied closure when the connection is open. When the \nFuture\n returned in the closure completes, the connection will be closed automatically.\n\n\nYou can also simply open a new connection with \nnewConnection(...)\n.\n\n\n// Creates a new connection to `.sqlite` db\n\n\nlet\n \nconn\n \n=\n \ntry\n \napp\n.\nnewConnection\n(\nto\n:\n \n.\nsqlite\n).\nwait\n()\n\n\n\n// Ensure the connection is closed when we exit this scope.\n\n\ndefer\n \n{\n \nconn\n.\nclose\n()\n \n}\n\n\n\n\n\n\nLogging\n\n\nDatabases can opt into supporting query logging via the \nLogSupporting\n protocol. Databases that conform to this protocol can have loggers \nconfigured\n via \nDatabasesConfig\n.\n\n\n// Enable logging on the SQLite database\n\n\ndbsConfig\n.\nenableLogging\n(\nfor\n:\n \n.\nsqlite\n)\n\n\n\n\n\n\nBy default, a simple print logger will be used, but you can pass a custom \nDatabaseLogHandler\n.\n\n\n// Create a custom log handler.\n\n\nlet\n \nmyLogger\n:\n \nDatabaseLogHandler\n \n=\n \n...\n\n\n\n// Enable logging on SQLite w/ custom logger.\n\n\ndbsConfig\n.\nenableLogging\n(\nfor\n:\n \n.\nsqlite\n,\n \nlogger\n:\n \nmyLogger\n)\n\n\n\n\n\n\nLog handlers will receive an instance of \nDatabaseLog\n for each logged query. This contains information such as the query, parameterized values, database id, and time.\n\n\nKeyed Cache\n\n\nDatabases can opt into supporting keyed-caching via the \nKeyedCacheSupporting\n protocol. Databases that conform to this protocol can be used to create instances of \nDatabaseKeyedCache\n.\n\n\nKeyed caches are capable of getting, setting, and removing \nCodable\n values at keys. They are sometimes called \"key value stores\".\n\n\nTo create a keyed cache, you can use the extensions on \nContainer\n.\n\n\n// Creates a DatabaseKeyedCache with .redis connection pool\n\n\nlet\n \ncache\n \n=\n \ntry\n \napp\n.\nkeyedCache\n(\nfor\n:\n \n.\nredis\n)\n\n\n\n// Sets \nhello\n = \nworld\n\n\ntry\n \ncache\n.\nset\n(\nhello\n,\n \nto\n:\n \nworld\n).\nwait\n()\n\n\n\n// Gets \nhello\n\n\nlet\n \nworld\n \n=\n \ntry\n \ncache\n.\nget\n(\nhello\n,\n \nas\n:\n \nString\n.\nself\n).\nwait\n()\n\n\nprint\n(\nworld\n)\n \n// \nworld\n\n\n\n// Removes \nhello\n\n\ntry\n \ncache\n.\nremove\n(\nhello\n).\nwait\n()\n\n\n\n\n\n\nSee the \nKeyedCache\n protocol for more information.\n\n\nAPI Docs\n\n\nCheck out the \nAPI docs\n for more in-depth information about DatabaseKit's APIs.", 
            "title": "Overview"
        }, 
        {
            "location": "/database-kit/overview/#using-database-kit", 
            "text": "Database Kit is a framework for configuring and working with database connections. It helps you do things like manage and pool connections, create keyed caches, and log queries.   Many of Vapor's packages such as the Fluent drivers, Redis, and Vapor core are built on top of Database Kit. This guide will walk you through some of the common APIs you might encounter when using Database Kit.", 
            "title": "Using Database Kit"
        }, 
        {
            "location": "/database-kit/overview/#config", 
            "text": "Your first interaction with Database Kit will most likely be with the  DatabasesConfig  struct. This type helps you configure one or more databases to your application and will ultimately yield a  Databases  struct. This usually takes place in  configure.swift .  // Create a SQLite database.  let   sqliteDB   =   SQLiteDatabase (...)  // Create a new, empty DatabasesConfig.  var   dbsConfig   =   DatabasesConfig ()  // Register the SQLite database using  .sqlite  as an identifier.  dbsConfig . add ( sqliteDB ,   as :   . sqlite )  // Register more DBs here if you want  // Register the DatabaseConfig to services.  services . register ( dbsConfig )   Using the  add(...)  methods, you can register  Database s to the config. You can register instances of a database, a database type, or a closure that creates a database. The latter two methods will be resolved when your container boots.  You can also configure options on your databases, such as enabling logging.  // Enable logging on the SQLite database  dbsConfig . enableLogging ( for :   . sqlite )   See the section on  logging  for more information.", 
            "title": "Config"
        }, 
        {
            "location": "/database-kit/overview/#identifier", 
            "text": "Most database integrations will provide a default  DatabaseIdentifier  to use. However, you can always create your own. This is usually done by creating a static extension.  extension   DatabaseIdentifier   { \n     /// Test database. \n     static   var   testing :   DatabaseIdentifier MySQLDatabase   { \n         return   testing \n     }  }   DatabaseIdentifier  is  ExpressibleByStringLiteral  which allows you to create one with just a  String .", 
            "title": "Identifier"
        }, 
        {
            "location": "/database-kit/overview/#databases", 
            "text": "Once you have registered a  DatabasesConfig  to your services and booted a container, you can take advantage of the convenience extensions on  Container  to start creating connections.  // Creates a new connection to `.sqlite` db  app . withNewConnection ( to :   . sqlite )   {   conn   in \n     return   conn . query (...)   // do some db query  }   Read more about creating and managing connections in the next section.", 
            "title": "Databases"
        }, 
        {
            "location": "/database-kit/overview/#connections", 
            "text": "Database Kit's main focus is on creating, managing, and pooling connections. Creating new connections takes a non-trivial amount of time for your application and many cloud services limit the total number of connections to a service that can be open. Because of this, it is important for high-concurrency web applications to manage their connections carefully.", 
            "title": "Connections"
        }, 
        {
            "location": "/database-kit/overview/#pools", 
            "text": "A common solution to connection management is the use of connection pools. These pools usually have a set maximum number of connections that are allowed to be open at once. Each time the pool is asked for a connection, it will first check if one is available before creating a new connection. If none are available, it will create a new one. If no connections are available and the pool is already at its maximum, the request for a new connection will  wait  for a connection to be returned.   The easiest way to request and release a pooled connection is the method  withPooledConnection(...) .   // Requests a pooled connection to `.psql` db  req . withPooledConnection ( to :   . psql )   {   conn   in \n     return   conn . query (...)   // do some db query  }   This method will requested a pooled connection to the identified database and call the provided closure when the connection is available. When the  Future  returned by the closure has completed, the connection will automatically be returned to the pool.  If you need access to a connection outside of a closure, you can use the related request / release methods instead.  // Request a connection from the pool and wait for it to be ready.  let   conn   =   try   app . requestPooledConnection ( to :   . psql ). wait ()  // Ensure the connection is released when we exit this scope.  defer   {   app . releasePooledConnection ( conn ,   to :   . psql )   }   You can configure your connection pools using the  DatabaseConnectionPoolConfig  struct.   // Create a new, empty pool config.  var   poolConfig   =   DatabaseConnectionPoolConfig ()  // Set max connections per pool to 8.  poolConfig . maxConnections   =   8  // Register the pool config.  services . register ( poolConfig )   To prevent race conditions, pools are never shared between event loops. There is usually one pool per database per event loop. This means that the amount of connections your application can potentially open to a given database is equal to  numThreads * maxConns .", 
            "title": "Pools"
        }, 
        {
            "location": "/database-kit/overview/#new", 
            "text": "You can always create a new connection to your databases if you need to. This will not affect your pooled connections. Creating new connections is especially useful during testing and app boot. But try not to do it in route closures since heavy traffic to your app could end up creating a lot of connections!  Similar to pooled connections, opening and closing new connections can be done using  withNewConnection(...) .   // Creates a new connection to `.sqlite` db  app . withNewConnection ( to :   . sqlite )   {   conn   in \n     return   conn . query (...)   // do some db query  }   This method will create a new connection, calling the supplied closure when the connection is open. When the  Future  returned in the closure completes, the connection will be closed automatically.  You can also simply open a new connection with  newConnection(...) .  // Creates a new connection to `.sqlite` db  let   conn   =   try   app . newConnection ( to :   . sqlite ). wait ()  // Ensure the connection is closed when we exit this scope.  defer   {   conn . close ()   }", 
            "title": "New"
        }, 
        {
            "location": "/database-kit/overview/#logging", 
            "text": "Databases can opt into supporting query logging via the  LogSupporting  protocol. Databases that conform to this protocol can have loggers  configured  via  DatabasesConfig .  // Enable logging on the SQLite database  dbsConfig . enableLogging ( for :   . sqlite )   By default, a simple print logger will be used, but you can pass a custom  DatabaseLogHandler .  // Create a custom log handler.  let   myLogger :   DatabaseLogHandler   =   ...  // Enable logging on SQLite w/ custom logger.  dbsConfig . enableLogging ( for :   . sqlite ,   logger :   myLogger )   Log handlers will receive an instance of  DatabaseLog  for each logged query. This contains information such as the query, parameterized values, database id, and time.", 
            "title": "Logging"
        }, 
        {
            "location": "/database-kit/overview/#keyed-cache", 
            "text": "Databases can opt into supporting keyed-caching via the  KeyedCacheSupporting  protocol. Databases that conform to this protocol can be used to create instances of  DatabaseKeyedCache .  Keyed caches are capable of getting, setting, and removing  Codable  values at keys. They are sometimes called \"key value stores\".  To create a keyed cache, you can use the extensions on  Container .  // Creates a DatabaseKeyedCache with .redis connection pool  let   cache   =   try   app . keyedCache ( for :   . redis )  // Sets  hello  =  world  try   cache . set ( hello ,   to :   world ). wait ()  // Gets  hello  let   world   =   try   cache . get ( hello ,   as :   String . self ). wait ()  print ( world )   //  world  // Removes  hello  try   cache . remove ( hello ). wait ()   See the  KeyedCache  protocol for more information.", 
            "title": "Keyed Cache"
        }, 
        {
            "location": "/database-kit/overview/#api-docs", 
            "text": "Check out the  API docs  for more in-depth information about DatabaseKit's APIs.", 
            "title": "API Docs"
        }, 
        {
            "location": "/fluent/getting-started/", 
            "text": "Warning\n\n\nFluent 3.0 is still in beta. Some documentation may be missing or out of date.\n\n\n\n\nGetting Started with Fluent\n\n\nFluent (\nvapor/fluent\n) is a type-safe, fast, and easy-to-use ORM framework built for Swift.\nIt takes advantage of Swift's strong type system to provide an elegant foundation for building database integrations.\n\n\nDatabase\n\n\nFluent is just a framework for building ORMs, not an ORM itself. To get started using Fluent, pick one of the databases below.\n\n\n\n\n\n\n\n\ndatabase\n\n\nlibrary\n\n\ndriver\n\n\nguide\n\n\n\n\n\n\n\n\n\n\nPostgreSQL\n\n\nvapor/postgresql\n\n\nvapor/fluent-postgresql\n\n\nGetting Started \n\n\n\n\n\n\nMySQL\n\n\nvapor/mysql\n\n\nvapor/fluent-mysql\n\n\nGetting Started \n\n\n\n\n\n\nSQLite\n\n\nvapor/sqlite\n\n\nvapor/fluent-sqlite\n\n\nGetting Started \n\n\n\n\n\n\n\n\nAfter you get started, come back to the other sections in this guide for a more in-depth look at Fluent's features.\n\n\n\n\nTip\n\n\nYou can also search GitHub for the tag \nfluent-database\n for a full list of official and third-party Fluent databases.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/fluent/getting-started/#getting-started-with-fluent", 
            "text": "Fluent ( vapor/fluent ) is a type-safe, fast, and easy-to-use ORM framework built for Swift.\nIt takes advantage of Swift's strong type system to provide an elegant foundation for building database integrations.", 
            "title": "Getting Started with Fluent"
        }, 
        {
            "location": "/fluent/getting-started/#database", 
            "text": "Fluent is just a framework for building ORMs, not an ORM itself. To get started using Fluent, pick one of the databases below.     database  library  driver  guide      PostgreSQL  vapor/postgresql  vapor/fluent-postgresql  Getting Started     MySQL  vapor/mysql  vapor/fluent-mysql  Getting Started     SQLite  vapor/sqlite  vapor/fluent-sqlite  Getting Started      After you get started, come back to the other sections in this guide for a more in-depth look at Fluent's features.   Tip  You can also search GitHub for the tag  fluent-database  for a full list of official and third-party Fluent databases.", 
            "title": "Database"
        }, 
        {
            "location": "/fluent/models/", 
            "text": "Fluent Models\n\n\nModels are the heart of Fluent. Unlike ORMs in other languages, Fluent doesn't return untyped arrays or dictionaries for queries. Instead, you query the database using models. This allows the Swift compiler to catch many errors that have burdened ORM users for ages.\n\n\n\n\nInfo\n\n\nThis guide provides an overview of the \nModel\n protocol and its associated methods and properties. If you are just getting started, check out the guide for your database at \nFluent \n Getting Started\n.\n\n\n\n\nModel\n is a protocol in the \nFluent\n module. It extends the \nAnyModel\n protocol which can be used for type-erasure. \n\n\nConformance\n\n\nBoth \nstruct\ns and \nclass\nes can conform to \nModel\n, however you must pay special attention to Fluent's return types if you use a \nstruct\n. Since Fluent works asynchronously, any mutations to a value-type (\nstruct\n) model must return a new copy of the model as a future result.\n\n\nNormally, you will conform your model to one of the convenience models available in your database-specific package (i.e., \nPostgreSQLModel\n). However, if you want to customize additional properties, such as the model's \nidKey\n, you will want to use the \nModel\n protocol itself.\n\n\nLet's take a look at what a basic \nModel\n conformance looks like.\n\n\n/// A simple user.\n\n\nfinal\n \nclass\n \nUser\n:\n \nModel\n \n{\n\n    \n/// See `Model.Database`\n\n    \ntypealias\n \nDatabase\n \n=\n \nFooDatabase\n\n\n    \n/// See `Model.ID`\n\n    \ntypealias\n \nID\n \n=\n \nInt\n\n\n    \n/// See `Model.idKey`\n\n    \nstatic\n \nlet\n \nidKey\n:\n \nIDKey\n \n=\n \n\\\n.\nid\n\n\n    \n/// The unique identifier for this user.\n\n    \nvar\n \nid\n:\n \nInt\n?\n\n\n    \n/// The user\ns full name.\n\n    \nvar\n \nname\n:\n \nString\n\n\n    \n/// The user\ns current age in years.\n\n    \nvar\n \nage\n:\n \nInt\n\n\n    \n/// Creates a new user.\n\n    \ninit\n(\nid\n:\n \nInt\n?\n \n=\n \nnil\n,\n \nname\n:\n \nString\n,\n \nage\n:\n \nInt\n)\n \n{\n\n        \nself\n.\nid\n \n=\n \nid\n\n        \nself\n.\nname\n \n=\n \nname\n\n        \nself\n.\nage\n \n=\n \nage\n\n    \n}\n\n\n}\n\n\n\n\n\n\n\n\nTip\n\n\nUsing \nfinal\n prevents your class from being sub-classed. This makes your life easier.\n\n\n\n\nAssociated Types\n\n\nModel\n defines a few associated types that help Fluent create type-safe APIs for you to use. Take a look at \nAnyModel\n if you need a type-erased version with no associated types.\n\n\nDatabase\n\n\nThis type indicates to Fluent which database you intend to use with this model. Using this information, Fluent can dynamically add appropriate methods and data types to any \nQueryBuilder\ns you create with this model.\n\n\nfinal\n \nclass\n \nUser\n:\n \nModel\n \n{\n\n    \n/// See `Model.Database`\n\n    \ntypealias\n \nDatabase\n \n=\n \nFooDatabase\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nIt is possible to make this associated type generic by adding a generic type to your class or struct (i.e, \nUser\nT\n). This is useful for cases where you are attempting to create generic extensions to Fluent, like perhaps an additive service provider.\n\n\nfinal\n \nclass\n \nUser\nD\n:\n \nModel\n \nwhere\n \nD\n:\n \nDatabase\n \n{\n\n    \n/// See `Model.Database`\n\n    \ntypealias\n \nDatabase\n \n=\n \nD\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nYou can add further conditions to \nD\n, such as \nQuerySupporting\n or \nSchemaSupporting\n. You can also dynamically extend and conform your generic model using \nextension User where D: ... { }\n.\n\n\nThat said, for most cases, you should stick to using a concrete type-alias wherever possible. Fluent 3 is designed to allow you to harness the power of your database by creating a strong connection between your models and the underlying driver. \n\n\nID\n\n\nThis property defines the type your model will use for its unique identifier.\n\n\nfinal\n \nclass\n \nUser\n:\n \nModel\n \n{\n\n    \n/// See `Model.ID`\n\n    \ntypealias\n \nID\n \n=\n \nUUID\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nThis will usually be something like \nInt\n, \nUUID\n, or \nString\n although you can theoretically use any type you like.\n\n\nProperties\n\n\nThere are several overridable properties on \nModel\n that you can use to customize how Fluent interacts with your database.\n\n\nName\n\n\nThis \nString\n will be used as a unique identifier for your model whenever Fluent needs one.\n\n\nfinal\n \nclass\n \nUser\n:\n \nModel\n \n{\n\n    \n/// See `Model.name`\n\n    \nstatic\n \nlet\n \nname\n \n=\n \nuser\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nBy default, this is the type name of your model lowercased.\n\n\nEntity\n\n\nEntity is a generic word used to mean either \"table\" or \"collection\", depending on which type of backend you are using for Fluent.\n\n\nfinal\n \nclass\n \nGoose\n:\n \nModel\n \n{\n\n    \n/// See `Model.entity`\n\n    \nstatic\n \nlet\n \nentity\n \n=\n \ngeese\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nBy default, this property will be \nname\n pluralized. Overriding this property is useful in situations where language fails you and the plural form of a word is very irregular.\n\n\nID Key\n\n\nThe ID key is a writeable \nkey path\n that points to your model's unique identifier property.\n\n\nUsually this will be a property named \nid\n (for some databases it is \n_id\n). However you can theoretically use any key you like.\n\n\nfinal\n \nclass\n \nUser\n:\n \nModel\n \n{\n\n    \n/// See `Model.ID`\n\n    \ntypealias\n \nID\n \n=\n \nString\n\n\n    \n/// See `Model.entity`\n\n    \nstatic\n \nlet\n \nidKey\n \n=\n \n\\\n.\nusername\n\n\n    \n/// The user\ns unique username\n\n    \nvar\n \nusername\n:\n \nString\n?\n\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nThe \nidKey\n property must point to an optional, writeable (\nvar\n) property with type matching \nID\n.\n\n\nLifecycle\n\n\nThere are several lifecycle methods on \nModel\n that you can override to hook into Fluent events.\n\n\n\n\n\n\n\n\nmethod\n\n\ndescription\n\n\nthrowing\n\n\n\n\n\n\n\n\n\n\nwillCreate\n\n\nCalled before Fluent saves your model (for the first time)\n\n\nCancels the save.\n\n\n\n\n\n\ndidCreate\n\n\nCalled after Fluent saves your model (for the first time)\n\n\nSave completes. Query fails.\n\n\n\n\n\n\nwillUpdate\n\n\nCalled before Fluent saves your model (subsequent saves)\n\n\nCancels the save.\n\n\n\n\n\n\ndidUpdate\n\n\nCalled after Fluent saves your model (subsequent saves)\n\n\nSave completes. Query fails.\n\n\n\n\n\n\nwillRead\n\n\nCalled before Fluent returns your model from a fetch query.\n\n\nCancels the fetch.\n\n\n\n\n\n\nwillDelete\n\n\nCalled before Fluent deletes your model.\n\n\nCancels the delete.\n\n\n\n\n\n\n\n\nHere's an example of overriding the \nwillUpdate(on:)\n method.\n\n\nfinal\n \nclass\n \nUser\n:\n \nModel\n \n{\n\n    \n/// ...\n\n\n    \n/// See `Model.willUpdate(on:)`\n\n    \nfunc\n \nwillUpdate\n(\non\n \nconnection\n:\n \nDatabase\n.\nConnection\n)\n \nthrows\n \n-\n \nFuture\nSelf\n \n{\n\n        \n/// Throws an error if the username is invalid\n\n        \ntry\n \nvalidateUsername\n()\n\n\n        \n/// Return the user. No async work is being done, so we must create a future manually.\n\n        \nreturn\n \nFuture\n.\nmap\n(\non\n:\n \nconnection\n)\n \n{\n \nself\n \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nCRUD\n\n\nThe model offers basic CRUD method (create, read, update, delete).\n\n\nCreate\n\n\nThis method creates a new row / item for an instance of your model in the database.\n\n\nIf your model does not have an ID, calls to \n.save(on:)\n will redirect to this method.\n\n\nlet\n \ndidCreate\n \n=\n \nuser\n.\ncreate\n(\non\n:\n \nreq\n)\n\n\nprint\n(\ndidCreate\n)\n \n/// Future\nUser\n\n\n\n\n\n\n\n\nInfo\n\n\nIf you are using a value-type (\nstruct\n), the instance of your model returned by \n.create(on:)\n will contain the model's new ID.\n\n\n\n\nRead\n\n\nTwo methods are important for reading your model from the database, \nfind(_:on:)\n and \nquery(on:)\n.\n\n\n/// Finds a user with ID == 1\n\n\nlet\n \nuser\n \n=\n \nUser\n.\nfind\n(\n1\n,\n \non\n:\n \nreq\n)\n\n\nprint\n(\nuser\n)\n \n/// Future\nUser?\n\n\n\n\n\n\n/// Finds all users with name == \nVapor\n\n\nlet\n \nusers\n \n=\n \nUser\n.\nquery\n(\non\n:\n \nreq\n).\nfilter\n(\n\\\n.\nname\n \n==\n \nVapor\n).\nall\n()\n\n\nprint\n(\nusers\n)\n \n/// Future\n[User]\n\n\n\n\n\n\nUpdate\n\n\nThis method updates the existing row / item associated with an instance of your model in the database.\n\n\nIf your model already has an ID, calls to \n.save(on:)\n will redirect to this method.\n\n\n/// Updates the user\n\n\nlet\n \ndidUpdate\n \n=\n \nuser\n.\nupdate\n(\non\n:\n \nreq\n)\n\n\nprint\n(\ndidUpdate\n)\n \n/// Future\nUser\n\n\n\n\n\n\nDelete\n\n\nThis method deletes the existing row / item associated with an instance of your model from the database.\n\n\n/// Deletes the user\n\n\nlet\n \ndidDelete\n \n=\n \nuser\n.\ndelete\n(\non\n:\n \nreq\n)\n\n\nprint\n(\ndidDelete\n)\n \n/// Future\nVoid\n\n\n\n\n\n\nMethods\n\n\nModel\n offers some convenience methods to make working with it easier.\n\n\nRequire ID\n\n\nThis method return's the models ID or throws an error.\n\n\nlet\n \nid\n \n=\n \ntry\n \nuser\n.\nrequireID\n()", 
            "title": "Models"
        }, 
        {
            "location": "/fluent/models/#fluent-models", 
            "text": "Models are the heart of Fluent. Unlike ORMs in other languages, Fluent doesn't return untyped arrays or dictionaries for queries. Instead, you query the database using models. This allows the Swift compiler to catch many errors that have burdened ORM users for ages.   Info  This guide provides an overview of the  Model  protocol and its associated methods and properties. If you are just getting started, check out the guide for your database at  Fluent   Getting Started .   Model  is a protocol in the  Fluent  module. It extends the  AnyModel  protocol which can be used for type-erasure.", 
            "title": "Fluent Models"
        }, 
        {
            "location": "/fluent/models/#conformance", 
            "text": "Both  struct s and  class es can conform to  Model , however you must pay special attention to Fluent's return types if you use a  struct . Since Fluent works asynchronously, any mutations to a value-type ( struct ) model must return a new copy of the model as a future result.  Normally, you will conform your model to one of the convenience models available in your database-specific package (i.e.,  PostgreSQLModel ). However, if you want to customize additional properties, such as the model's  idKey , you will want to use the  Model  protocol itself.  Let's take a look at what a basic  Model  conformance looks like.  /// A simple user.  final   class   User :   Model   { \n     /// See `Model.Database` \n     typealias   Database   =   FooDatabase \n\n     /// See `Model.ID` \n     typealias   ID   =   Int \n\n     /// See `Model.idKey` \n     static   let   idKey :   IDKey   =   \\ . id \n\n     /// The unique identifier for this user. \n     var   id :   Int ? \n\n     /// The user s full name. \n     var   name :   String \n\n     /// The user s current age in years. \n     var   age :   Int \n\n     /// Creates a new user. \n     init ( id :   Int ?   =   nil ,   name :   String ,   age :   Int )   { \n         self . id   =   id \n         self . name   =   name \n         self . age   =   age \n     }  }    Tip  Using  final  prevents your class from being sub-classed. This makes your life easier.", 
            "title": "Conformance"
        }, 
        {
            "location": "/fluent/models/#associated-types", 
            "text": "Model  defines a few associated types that help Fluent create type-safe APIs for you to use. Take a look at  AnyModel  if you need a type-erased version with no associated types.", 
            "title": "Associated Types"
        }, 
        {
            "location": "/fluent/models/#database", 
            "text": "This type indicates to Fluent which database you intend to use with this model. Using this information, Fluent can dynamically add appropriate methods and data types to any  QueryBuilder s you create with this model.  final   class   User :   Model   { \n     /// See `Model.Database` \n     typealias   Database   =   FooDatabase \n     /// ...  }   It is possible to make this associated type generic by adding a generic type to your class or struct (i.e,  User T ). This is useful for cases where you are attempting to create generic extensions to Fluent, like perhaps an additive service provider.  final   class   User D :   Model   where   D :   Database   { \n     /// See `Model.Database` \n     typealias   Database   =   D \n     /// ...  }   You can add further conditions to  D , such as  QuerySupporting  or  SchemaSupporting . You can also dynamically extend and conform your generic model using  extension User where D: ... { } .  That said, for most cases, you should stick to using a concrete type-alias wherever possible. Fluent 3 is designed to allow you to harness the power of your database by creating a strong connection between your models and the underlying driver.", 
            "title": "Database"
        }, 
        {
            "location": "/fluent/models/#id", 
            "text": "This property defines the type your model will use for its unique identifier.  final   class   User :   Model   { \n     /// See `Model.ID` \n     typealias   ID   =   UUID \n     /// ...  }   This will usually be something like  Int ,  UUID , or  String  although you can theoretically use any type you like.", 
            "title": "ID"
        }, 
        {
            "location": "/fluent/models/#properties", 
            "text": "There are several overridable properties on  Model  that you can use to customize how Fluent interacts with your database.", 
            "title": "Properties"
        }, 
        {
            "location": "/fluent/models/#name", 
            "text": "This  String  will be used as a unique identifier for your model whenever Fluent needs one.  final   class   User :   Model   { \n     /// See `Model.name` \n     static   let   name   =   user \n     /// ...  }   By default, this is the type name of your model lowercased.", 
            "title": "Name"
        }, 
        {
            "location": "/fluent/models/#entity", 
            "text": "Entity is a generic word used to mean either \"table\" or \"collection\", depending on which type of backend you are using for Fluent.  final   class   Goose :   Model   { \n     /// See `Model.entity` \n     static   let   entity   =   geese \n     /// ...  }   By default, this property will be  name  pluralized. Overriding this property is useful in situations where language fails you and the plural form of a word is very irregular.", 
            "title": "Entity"
        }, 
        {
            "location": "/fluent/models/#id-key", 
            "text": "The ID key is a writeable  key path  that points to your model's unique identifier property.  Usually this will be a property named  id  (for some databases it is  _id ). However you can theoretically use any key you like.  final   class   User :   Model   { \n     /// See `Model.ID` \n     typealias   ID   =   String \n\n     /// See `Model.entity` \n     static   let   idKey   =   \\ . username \n\n     /// The user s unique username \n     var   username :   String ? \n\n     /// ...  }   The  idKey  property must point to an optional, writeable ( var ) property with type matching  ID .", 
            "title": "ID Key"
        }, 
        {
            "location": "/fluent/models/#lifecycle", 
            "text": "There are several lifecycle methods on  Model  that you can override to hook into Fluent events.     method  description  throwing      willCreate  Called before Fluent saves your model (for the first time)  Cancels the save.    didCreate  Called after Fluent saves your model (for the first time)  Save completes. Query fails.    willUpdate  Called before Fluent saves your model (subsequent saves)  Cancels the save.    didUpdate  Called after Fluent saves your model (subsequent saves)  Save completes. Query fails.    willRead  Called before Fluent returns your model from a fetch query.  Cancels the fetch.    willDelete  Called before Fluent deletes your model.  Cancels the delete.     Here's an example of overriding the  willUpdate(on:)  method.  final   class   User :   Model   { \n     /// ... \n\n     /// See `Model.willUpdate(on:)` \n     func   willUpdate ( on   connection :   Database . Connection )   throws   -   Future Self   { \n         /// Throws an error if the username is invalid \n         try   validateUsername () \n\n         /// Return the user. No async work is being done, so we must create a future manually. \n         return   Future . map ( on :   connection )   {   self   } \n     }  }", 
            "title": "Lifecycle"
        }, 
        {
            "location": "/fluent/models/#crud", 
            "text": "The model offers basic CRUD method (create, read, update, delete).", 
            "title": "CRUD"
        }, 
        {
            "location": "/fluent/models/#create", 
            "text": "This method creates a new row / item for an instance of your model in the database.  If your model does not have an ID, calls to  .save(on:)  will redirect to this method.  let   didCreate   =   user . create ( on :   req )  print ( didCreate )   /// Future User    Info  If you are using a value-type ( struct ), the instance of your model returned by  .create(on:)  will contain the model's new ID.", 
            "title": "Create"
        }, 
        {
            "location": "/fluent/models/#read", 
            "text": "Two methods are important for reading your model from the database,  find(_:on:)  and  query(on:) .  /// Finds a user with ID == 1  let   user   =   User . find ( 1 ,   on :   req )  print ( user )   /// Future User?   /// Finds all users with name ==  Vapor  let   users   =   User . query ( on :   req ). filter ( \\ . name   ==   Vapor ). all ()  print ( users )   /// Future [User]", 
            "title": "Read"
        }, 
        {
            "location": "/fluent/models/#update", 
            "text": "This method updates the existing row / item associated with an instance of your model in the database.  If your model already has an ID, calls to  .save(on:)  will redirect to this method.  /// Updates the user  let   didUpdate   =   user . update ( on :   req )  print ( didUpdate )   /// Future User", 
            "title": "Update"
        }, 
        {
            "location": "/fluent/models/#delete", 
            "text": "This method deletes the existing row / item associated with an instance of your model from the database.  /// Deletes the user  let   didDelete   =   user . delete ( on :   req )  print ( didDelete )   /// Future Void", 
            "title": "Delete"
        }, 
        {
            "location": "/fluent/models/#methods", 
            "text": "Model  offers some convenience methods to make working with it easier.", 
            "title": "Methods"
        }, 
        {
            "location": "/fluent/models/#require-id", 
            "text": "This method return's the models ID or throws an error.  let   id   =   try   user . requireID ()", 
            "title": "Require ID"
        }, 
        {
            "location": "/fluent/migrations/", 
            "text": "Getting Started with Migrations\n\n\nMigrations are a way of making organized, testable, and reliable changes to your database's structure--\neven while it's in production!\n\n\nMigrations are often used for preparing a database schema for your models. However, they can also be used to \nmake normal queries to your database.\n\n\nIn this guide we will cover creating both types of migrations.\n\n\nModel Schema\n\n\nLet's take a look at how we can prepare a schema supporting database to accept the \n\nUser\n model from the \nprevious section\n.\n\n\nJust like we did with the \nModel\n protocol, we will conform our \nUser\n to \nMigration\n.\n\n\nimport\n \nFluent\n\n\n\nextension\n \nUser\n:\n \nMigration\n \n{\n\n\n\n}\n\n\n\n\n\n\nSwift will inform us that \nUser\n does not yet conform. Let's add the required methods!\n\n\nPrepare\n\n\nThe first method to implement is \nprepare\n. This method is where you make any of your \ndesired changes to the database.\n\n\nFor our \nUser\n model, we simply want to create a table that can store one or more users. To do this,\nwe will use the \n.create(...)\n function on the supplied database connection.\n\n\nextension\n \nUser\n:\n \nMigration\n \n{\n\n    \n/// See Migration.prepare\n\n    \nstatic\n \nfunc\n \nprepare\n(\non\n \nconnection\n:\n \nMySQLConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \nconnection\n.\ncreate\n(\nself\n)\n \n{\n \nbuilder\n \nin\n\n            \ntry\n \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nid\n)\n\n            \ntry\n \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nname\n)\n\n            \ntry\n \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nage\n)\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nWe pass \nself\n (shorthand for \nUser.self\n since this is a static method) as the first argument to the \n.create\n method. This indicates\nto Fluent that we would like to create a schema for the \nUser\n model.\n\n\nNext, we pass a closure that accepts a \nSchemaBuilder\n for our \nUser\n model.\nWe can then call \n.field\non this builder to describe what fields we'd like our table to have.\n\n\nSince we are passing key paths to our \nUser\n model (indicated by \n\\.\n), Fluent can see what type those properties are.\nFor most common types (\nString\n, \nInt\n, \nDouble\n, etc) Fluent will automatically be able to determine the best\ndatabase field type to use.\n\n\nYou can also choose to manually select which database field type to use for a given field.\n\n\ntry\n \nbuilder\n.\nfield\n(\ntype\n:\n \n.\ntext\n,\n \nfor\n:\n \n\\\n.\nname\n)\n\n\n\n\n\n\nLearn more about creating, updating, and deleting schemas in \nFluent \n Schema Builder\n.\n\n\nRevert\n\n\nRevert is the opposite of prepare. Its job is to undo anything that was done in prepare. It is used when you boot your \napp with the \n--revert\n option. \n\n\nTo implement \nrevert\n for our model, we simply use \n.delete\n to indicate that we would like to delete the schema created for \nUser\n.\n\n\nextension\n \nUser\n:\n \nMigration\n \n{\n\n    \n/// See Migration.revert\n\n    \nstatic\n \nfunc\n \nrevert\n(\non\n \nconnection\n:\n \nMySQLConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \nconnection\n.\ndelete\n(\nself\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nExample\n\n\nWe now have a fully functioning model with migration!\n\n\nextension\n \nTestUser\n:\n \nMigration\n \n{\n\n    \n/// See Migration.prepare\n\n    \nstatic\n \nfunc\n \nprepare\n(\non\n \nconnection\n:\n \nSQLiteConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \nconnection\n.\ncreate\n(\nself\n)\n \n{\n \nbuilder\n \nin\n\n            \ntry\n \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nid\n)\n\n            \ntry\n \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nname\n)\n\n            \ntry\n \nbuilder\n.\nfield\n(\nfor\n:\n \n\\\n.\nage\n)\n\n        \n}\n\n    \n}\n\n\n    \n/// See Migration.revert\n\n    \nstatic\n \nfunc\n \nrevert\n(\non\n \nconnection\n:\n \nSQLiteConnection\n)\n \n-\n \nFuture\nVoid\n \n{\n\n        \nreturn\n \nconnection\n.\ndelete\n(\nself\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nDone\n\n\nNow that you have a working Fluent model and migration, you can move onto \nquerying\n your model.", 
            "title": "Migrations"
        }, 
        {
            "location": "/fluent/migrations/#getting-started-with-migrations", 
            "text": "Migrations are a way of making organized, testable, and reliable changes to your database's structure--\neven while it's in production!  Migrations are often used for preparing a database schema for your models. However, they can also be used to \nmake normal queries to your database.  In this guide we will cover creating both types of migrations.", 
            "title": "Getting Started with Migrations"
        }, 
        {
            "location": "/fluent/migrations/#model-schema", 
            "text": "Let's take a look at how we can prepare a schema supporting database to accept the  User  model from the  previous section .  Just like we did with the  Model  protocol, we will conform our  User  to  Migration .  import   Fluent  extension   User :   Migration   {  }   Swift will inform us that  User  does not yet conform. Let's add the required methods!", 
            "title": "Model Schema"
        }, 
        {
            "location": "/fluent/migrations/#prepare", 
            "text": "The first method to implement is  prepare . This method is where you make any of your \ndesired changes to the database.  For our  User  model, we simply want to create a table that can store one or more users. To do this,\nwe will use the  .create(...)  function on the supplied database connection.  extension   User :   Migration   { \n     /// See Migration.prepare \n     static   func   prepare ( on   connection :   MySQLConnection )   -   Future Void   { \n         return   connection . create ( self )   {   builder   in \n             try   builder . field ( for :   \\ . id ) \n             try   builder . field ( for :   \\ . name ) \n             try   builder . field ( for :   \\ . age ) \n         } \n     }  }   We pass  self  (shorthand for  User.self  since this is a static method) as the first argument to the  .create  method. This indicates\nto Fluent that we would like to create a schema for the  User  model.  Next, we pass a closure that accepts a  SchemaBuilder  for our  User  model.\nWe can then call  .field on this builder to describe what fields we'd like our table to have.  Since we are passing key paths to our  User  model (indicated by  \\. ), Fluent can see what type those properties are.\nFor most common types ( String ,  Int ,  Double , etc) Fluent will automatically be able to determine the best\ndatabase field type to use.  You can also choose to manually select which database field type to use for a given field.  try   builder . field ( type :   . text ,   for :   \\ . name )   Learn more about creating, updating, and deleting schemas in  Fluent   Schema Builder .", 
            "title": "Prepare"
        }, 
        {
            "location": "/fluent/migrations/#revert", 
            "text": "Revert is the opposite of prepare. Its job is to undo anything that was done in prepare. It is used when you boot your \napp with the  --revert  option.   To implement  revert  for our model, we simply use  .delete  to indicate that we would like to delete the schema created for  User .  extension   User :   Migration   { \n     /// See Migration.revert \n     static   func   revert ( on   connection :   MySQLConnection )   -   Future Void   { \n         return   connection . delete ( self ) \n     }  }", 
            "title": "Revert"
        }, 
        {
            "location": "/fluent/migrations/#example", 
            "text": "We now have a fully functioning model with migration!  extension   TestUser :   Migration   { \n     /// See Migration.prepare \n     static   func   prepare ( on   connection :   SQLiteConnection )   -   Future Void   { \n         return   connection . create ( self )   {   builder   in \n             try   builder . field ( for :   \\ . id ) \n             try   builder . field ( for :   \\ . name ) \n             try   builder . field ( for :   \\ . age ) \n         } \n     } \n\n     /// See Migration.revert \n     static   func   revert ( on   connection :   SQLiteConnection )   -   Future Void   { \n         return   connection . delete ( self ) \n     }  }", 
            "title": "Example"
        }, 
        {
            "location": "/fluent/migrations/#done", 
            "text": "Now that you have a working Fluent model and migration, you can move onto  querying  your model.", 
            "title": "Done"
        }, 
        {
            "location": "/fluent/querying/", 
            "text": "Querying Models\n\n\nOnce you have a \nmodel\n (and optionally a \nmigration\n) you can start\nquerying your database to create, read, update, and delete data.\n\n\nConnection\n\n\nThe first thing you need to query your database, is a connection to it. Luckily, they are easy to get.\n\n\nYou can use either the application or an incoming request to create a database connection. You just need\naccess to the database identifier.\n\n\nRequest\n\n\nThe preferred method for getting access to a database connection is via an incoming request.\n\n\nrouter\n.\nget\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \nin\n\n        \n// use the db here\n\n    \n}\n\n\n}\n\n\n\n\n\n\nThe first parameter is the database's identifier. The second parameter is a closure\nthat accepts a connection to that database.\n\n\n\n\nTip\n\n\nAlthough the closure to \n.withConnection(to: ...)\n accepts a database \nconnection\n, we often use just \ndb\n for short.\n\n\n\n\nThe closure is expected to return a \nFuture\nVoid\n. When this future is completed, the connection will be released\nback into Fluent's connection pool. This is usually acheived by simply returning the query as we will soon see.\n\n\nApplication\n\n\nYou can also create a database connection using the application. This is useful for cases where you must access\nthe database from outside a request/response event.\n\n\nlet\n \nres\n \n=\n \napp\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \nin\n\n    \n// use the db here\n\n\n}\n\n\nprint\n(\nres\n)\n \n// Future\nT\n\n\n\n\n\n\nThis is usually done in the \nboot section\n of your application.\n\n\n\n\nWarning\n\n\nDo not use database connections created by the application in a route closure (when responding to a request).\nAlways use the incoming request to create a connection to avoid threading issues.\n\n\n\n\nCreate\n\n\nTo create (save) a model to the database, first initialize an instance of your model, then call \n.save(on: )\n.\n\n\nrouter\n.\npost\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \n-\n \nFuture\nUser\n \nin\n\n        \nlet\n \nuser\n \n=\n \nUser\n(\nname\n:\n \nVapor\n,\n \nage\n:\n \n3\n)\n\n        \nreturn\n \nuser\n.\nsave\n(\non\n:\n \ndb\n).\ntransform\n(\nto\n:\n \nuser\n)\n \n// Future\nUser\n\n    \n}\n\n\n}\n\n\n\n\n\n\nResponse\n\n\n.save(on: )\n returns a \nFuture\nVoid\n that completes when the user has finished saving. In this example, we then\nmap that \nFuture\nVoid\n to a \nFuture\nUser\n by calling \n.map\n and passing in the recently-saved user.\n\n\nYou can also use \n.map\n to return a simple success response.\n\n\nrouter\n.\npost\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \n-\n \nFuture\nHTTPResponse\n \nin\n\n        \nlet\n \nuser\n \n=\n \nUser\n(\nname\n:\n \nVapor\n,\n \nage\n:\n \n3\n)\n\n        \nreturn\n \nuser\n.\nsave\n(\non\n:\n \ndb\n).\nmap\n(\nto\n:\n \nHTTPResponse\n.\nself\n)\n \n{\n\n            \nreturn\n \nHTTPResponse\n(\nstatus\n:\n \n.\ncreated\n)\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nMultiple\n\n\nIf you have multiple instances to save, do so using an array. Arrays containing only futures behave like futures.\n\n\nrouter\n.\npost\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \n-\n \nFuture\nHTTPResponse\n \nin\n\n        \nlet\n \nmarie\n \n=\n \nUser\n(\nname\n:\n \nMarie Curie\n,\n \nage\n:\n \n66\n)\n\n        \nlet\n \ncharles\n \n=\n \nUser\n(\nname\n:\n \nCharles Darwin\n,\n \nage\n:\n \n73\n)\n\n        \nreturn\n \n[\n\n            \nmarie\n.\nsave\n(\non\n:\n \ndb\n),\n\n            \ncharles\n.\nsave\n(\non\n:\n \ndb\n)\n\n        \n].\nmap\n(\nto\n:\n \nHTTPResponse\n.\nself\n)\n \n{\n\n            \nreturn\n \nHTTPResponse\n(\nstatus\n:\n \n.\ncreated\n)\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nRead\n\n\nTo read models from the database, use \n.query()\n on the database connection to create a \nQueryBuilder\n.\n\n\nAll\n\n\nFetch all instances of a model from the database using \n.all()\n.\n\n\nrouter\n.\nget\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \n-\n \nFuture\n[\nUser\n]\n \nin\n\n        \nreturn\n \ndb\n.\nquery\n(\nUser\n.\nself\n).\nall\n()\n\n    \n}\n\n\n}\n\n\n\n\n\n\nFilter\n\n\nUse \n.filter(...)\n to apply \nfilters\n to your query.\n\n\nrouter\n.\nget\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \n-\n \nFuture\n[\nUser\n]\n \nin\n\n        \nreturn\n \ntry\n \ndb\n.\nquery\n(\nUser\n.\nself\n).\nfilter\n(\n\\\nUser\n.\nage\n \n \n50\n).\nall\n()\n\n    \n}\n\n\n}\n\n\n\n\n\n\nFirst\n\n\nYou can also use \n.first()\n to just get the first result.\n\n\nrouter\n.\nget\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \n-\n \nFuture\nUser\n \nin\n\n        \nreturn\n \ntry\n \ndb\n.\nquery\n(\nUser\n.\nself\n).\nfilter\n(\n\\\nUser\n.\nname\n \n==\n \nVapor\n).\nfirst\n().\nmap\n(\nto\n:\n \nUser\n.\nself\n)\n \n{\n \nuser\n \nin\n\n            \nguard\n \nlet\n \nuser\n \n=\n \nuser\n \nelse\n \n{\n\n                \nthrow\n \nAbort\n(.\nnotFound\n,\n \nreason\n:\n \nCould not find user.\n)\n\n            \n}\n\n\n            \nreturn\n \nuser\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nNotice we use \n.map(to:)\n here to convert the optional user returned by \n.first()\n to a non-optional\nuser, or we throw an error.\n\n\nUpdate\n\n\nrouter\n.\nput\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \n-\n \nFuture\nUser\n \nin\n\n        \nreturn\n \ndb\n.\nquery\n(\nUser\n.\nself\n).\nfirst\n().\nmap\n(\nto\n:\n \nUser\n.\nself\n)\n \n{\n \nuser\n \nin\n\n            \nguard\n \nlet\n \nuser\n \n=\n \n$0\n \nelse\n \n{\n\n                \nthrow\n \nAbort\n(.\nnotFound\n,\n \nreason\n:\n \nCould not find user.\n)\n\n            \n}\n\n\n            \nreturn\n \nuser\n\n        \n}.\nflatMap\n(\nto\n:\n \nUser\n.\nself\n)\n \n{\n \nuser\n \nin\n\n            \nuser\n.\nage\n \n+=\n \n1\n\n            \nreturn\n \nuser\n.\nupdate\n(\non\n:\n \ndb\n).\nmap\n(\nto\n:\n \nUser\n.\nself\n)\n \n{\n \nuser\n \n}\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nNotice we use \n.map(to:)\n here to convert the optional user returned by \n.first()\n to a non-optional\nuser, or we throw an error.\n\n\nDelete\n\n\nrouter\n.\ndelete\n(...)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nfoo\n)\n \n{\n \ndb\n \n-\n \nFuture\nUser\n \nin\n\n        \nreturn\n \ndb\n.\nquery\n(\nUser\n.\nself\n).\nfirst\n().\nmap\n(\nto\n:\n \nUser\n.\nself\n)\n \n{\n \nuser\n \nin\n\n            \nguard\n \nlet\n \nuser\n \n=\n \n$0\n \nelse\n \n{\n\n                \nthrow\n \nAbort\n(.\nnotFound\n,\n \nreason\n:\n \nCould not find user.\n)\n\n            \n}\n\n            \nreturn\n \nuser\n\n        \n}.\nflatMap\n(\nto\n:\n \nUser\n.\nself\n)\n \n{\n \nuser\n \nin\n\n            \nreturn\n \nuser\n.\ndelete\n(\non\n:\n \ndb\n).\ntransfom\n(\nto\n:\n \nuser\n)\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nNotice we use \n.map(to:)\n here to convert the optional user returned by \n.first()\n to a non-optional\nuser, or we throw an error.", 
            "title": "Querying"
        }, 
        {
            "location": "/fluent/querying/#querying-models", 
            "text": "Once you have a  model  (and optionally a  migration ) you can start\nquerying your database to create, read, update, and delete data.", 
            "title": "Querying Models"
        }, 
        {
            "location": "/fluent/querying/#connection", 
            "text": "The first thing you need to query your database, is a connection to it. Luckily, they are easy to get.  You can use either the application or an incoming request to create a database connection. You just need\naccess to the database identifier.", 
            "title": "Connection"
        }, 
        {
            "location": "/fluent/querying/#request", 
            "text": "The preferred method for getting access to a database connection is via an incoming request.  router . get (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   in \n         // use the db here \n     }  }   The first parameter is the database's identifier. The second parameter is a closure\nthat accepts a connection to that database.   Tip  Although the closure to  .withConnection(to: ...)  accepts a database  connection , we often use just  db  for short.   The closure is expected to return a  Future Void . When this future is completed, the connection will be released\nback into Fluent's connection pool. This is usually acheived by simply returning the query as we will soon see.", 
            "title": "Request"
        }, 
        {
            "location": "/fluent/querying/#application", 
            "text": "You can also create a database connection using the application. This is useful for cases where you must access\nthe database from outside a request/response event.  let   res   =   app . withConnection ( to :   . foo )   {   db   in \n     // use the db here  }  print ( res )   // Future T   This is usually done in the  boot section  of your application.   Warning  Do not use database connections created by the application in a route closure (when responding to a request).\nAlways use the incoming request to create a connection to avoid threading issues.", 
            "title": "Application"
        }, 
        {
            "location": "/fluent/querying/#create", 
            "text": "To create (save) a model to the database, first initialize an instance of your model, then call  .save(on: ) .  router . post (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   -   Future User   in \n         let   user   =   User ( name :   Vapor ,   age :   3 ) \n         return   user . save ( on :   db ). transform ( to :   user )   // Future User \n     }  }", 
            "title": "Create"
        }, 
        {
            "location": "/fluent/querying/#response", 
            "text": ".save(on: )  returns a  Future Void  that completes when the user has finished saving. In this example, we then\nmap that  Future Void  to a  Future User  by calling  .map  and passing in the recently-saved user.  You can also use  .map  to return a simple success response.  router . post (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   -   Future HTTPResponse   in \n         let   user   =   User ( name :   Vapor ,   age :   3 ) \n         return   user . save ( on :   db ). map ( to :   HTTPResponse . self )   { \n             return   HTTPResponse ( status :   . created ) \n         } \n     }  }", 
            "title": "Response"
        }, 
        {
            "location": "/fluent/querying/#multiple", 
            "text": "If you have multiple instances to save, do so using an array. Arrays containing only futures behave like futures.  router . post (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   -   Future HTTPResponse   in \n         let   marie   =   User ( name :   Marie Curie ,   age :   66 ) \n         let   charles   =   User ( name :   Charles Darwin ,   age :   73 ) \n         return   [ \n             marie . save ( on :   db ), \n             charles . save ( on :   db ) \n         ]. map ( to :   HTTPResponse . self )   { \n             return   HTTPResponse ( status :   . created ) \n         } \n     }  }", 
            "title": "Multiple"
        }, 
        {
            "location": "/fluent/querying/#read", 
            "text": "To read models from the database, use  .query()  on the database connection to create a  QueryBuilder .", 
            "title": "Read"
        }, 
        {
            "location": "/fluent/querying/#all", 
            "text": "Fetch all instances of a model from the database using  .all() .  router . get (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   -   Future [ User ]   in \n         return   db . query ( User . self ). all () \n     }  }", 
            "title": "All"
        }, 
        {
            "location": "/fluent/querying/#filter", 
            "text": "Use  .filter(...)  to apply  filters  to your query.  router . get (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   -   Future [ User ]   in \n         return   try   db . query ( User . self ). filter ( \\ User . age     50 ). all () \n     }  }", 
            "title": "Filter"
        }, 
        {
            "location": "/fluent/querying/#first", 
            "text": "You can also use  .first()  to just get the first result.  router . get (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   -   Future User   in \n         return   try   db . query ( User . self ). filter ( \\ User . name   ==   Vapor ). first (). map ( to :   User . self )   {   user   in \n             guard   let   user   =   user   else   { \n                 throw   Abort (. notFound ,   reason :   Could not find user. ) \n             } \n\n             return   user \n         } \n     }  }   Notice we use  .map(to:)  here to convert the optional user returned by  .first()  to a non-optional\nuser, or we throw an error.", 
            "title": "First"
        }, 
        {
            "location": "/fluent/querying/#update", 
            "text": "router . put (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   -   Future User   in \n         return   db . query ( User . self ). first (). map ( to :   User . self )   {   user   in \n             guard   let   user   =   $0   else   { \n                 throw   Abort (. notFound ,   reason :   Could not find user. ) \n             } \n\n             return   user \n         }. flatMap ( to :   User . self )   {   user   in \n             user . age   +=   1 \n             return   user . update ( on :   db ). map ( to :   User . self )   {   user   } \n         } \n     }  }   Notice we use  .map(to:)  here to convert the optional user returned by  .first()  to a non-optional\nuser, or we throw an error.", 
            "title": "Update"
        }, 
        {
            "location": "/fluent/querying/#delete", 
            "text": "router . delete (...)   {   req   in \n     return   req . withConnection ( to :   . foo )   {   db   -   Future User   in \n         return   db . query ( User . self ). first (). map ( to :   User . self )   {   user   in \n             guard   let   user   =   $0   else   { \n                 throw   Abort (. notFound ,   reason :   Could not find user. ) \n             } \n             return   user \n         }. flatMap ( to :   User . self )   {   user   in \n             return   user . delete ( on :   db ). transfom ( to :   user ) \n         } \n     }  }   Notice we use  .map(to:)  here to convert the optional user returned by  .first()  to a non-optional\nuser, or we throw an error.", 
            "title": "Delete"
        }, 
        {
            "location": "/fluent/query-builder/", 
            "text": "Fluent Query Builder\n\n\nComing soon.\n\n\nFilter\n\n\nComing soon.\n\n\nCompare\n\n\nComing soon.\n\n\nGroup\n\n\nComing soon.\n\n\nSubset\n\n\nComing soon.\n\n\nJoin\n\n\nComing soon.\n\n\nRange\n\n\nComing soon.\n\n\nSort\n\n\nComing soon.\n\n\nExecute\n\n\nComing soon.\n\n\nAggregate\n\n\nComing soon.\n\n\nAll\n\n\nComing soon.\n\n\nFirst\n\n\nComing soon.\n\n\nQuery\n\n\nComing soon.", 
            "title": "Query Builder"
        }, 
        {
            "location": "/fluent/query-builder/#fluent-query-builder", 
            "text": "Coming soon.", 
            "title": "Fluent Query Builder"
        }, 
        {
            "location": "/fluent/query-builder/#filter", 
            "text": "Coming soon.", 
            "title": "Filter"
        }, 
        {
            "location": "/fluent/query-builder/#compare", 
            "text": "Coming soon.", 
            "title": "Compare"
        }, 
        {
            "location": "/fluent/query-builder/#group", 
            "text": "Coming soon.", 
            "title": "Group"
        }, 
        {
            "location": "/fluent/query-builder/#subset", 
            "text": "Coming soon.", 
            "title": "Subset"
        }, 
        {
            "location": "/fluent/query-builder/#join", 
            "text": "Coming soon.", 
            "title": "Join"
        }, 
        {
            "location": "/fluent/query-builder/#range", 
            "text": "Coming soon.", 
            "title": "Range"
        }, 
        {
            "location": "/fluent/query-builder/#sort", 
            "text": "Coming soon.", 
            "title": "Sort"
        }, 
        {
            "location": "/fluent/query-builder/#execute", 
            "text": "Coming soon.", 
            "title": "Execute"
        }, 
        {
            "location": "/fluent/query-builder/#aggregate", 
            "text": "Coming soon.", 
            "title": "Aggregate"
        }, 
        {
            "location": "/fluent/query-builder/#all", 
            "text": "Coming soon.", 
            "title": "All"
        }, 
        {
            "location": "/fluent/query-builder/#first", 
            "text": "Coming soon.", 
            "title": "First"
        }, 
        {
            "location": "/fluent/query-builder/#query", 
            "text": "Coming soon.", 
            "title": "Query"
        }, 
        {
            "location": "/fluent/schema-builder/", 
            "text": "Fluent Schema Builder\n\n\nComing soon.\n\n\nCreate\n\n\nComing soon.\n\n\nUpdate\n\n\nComing soon.\n\n\nDelete\n\n\nComing soon.\n\n\nReferences\n\n\nComing soon.", 
            "title": "Schema Builder"
        }, 
        {
            "location": "/fluent/schema-builder/#fluent-schema-builder", 
            "text": "Coming soon.", 
            "title": "Fluent Schema Builder"
        }, 
        {
            "location": "/fluent/schema-builder/#create", 
            "text": "Coming soon.", 
            "title": "Create"
        }, 
        {
            "location": "/fluent/schema-builder/#update", 
            "text": "Coming soon.", 
            "title": "Update"
        }, 
        {
            "location": "/fluent/schema-builder/#delete", 
            "text": "Coming soon.", 
            "title": "Delete"
        }, 
        {
            "location": "/fluent/schema-builder/#references", 
            "text": "Coming soon.", 
            "title": "References"
        }, 
        {
            "location": "/fluent/relations/", 
            "text": "Fluent Relations\n\n\nComing soon.\n\n\nParent / Child\n\n\nComing soon.\n\n\nSiblings\n\n\nComing soon.", 
            "title": "Relations"
        }, 
        {
            "location": "/fluent/relations/#fluent-relations", 
            "text": "Coming soon.", 
            "title": "Fluent Relations"
        }, 
        {
            "location": "/fluent/relations/#parent-child", 
            "text": "Coming soon.", 
            "title": "Parent / Child"
        }, 
        {
            "location": "/fluent/relations/#siblings", 
            "text": "Coming soon.", 
            "title": "Siblings"
        }, 
        {
            "location": "/fluent/pivot/", 
            "text": "Fluent Pivot\n\n\nComing soon.", 
            "title": "Pivot"
        }, 
        {
            "location": "/fluent/pivot/#fluent-pivot", 
            "text": "Coming soon.", 
            "title": "Fluent Pivot"
        }, 
        {
            "location": "/fluent/transaction/", 
            "text": "Fluent Transactions\n\n\nComing soon.", 
            "title": "Transaction"
        }, 
        {
            "location": "/fluent/transaction/#fluent-transactions", 
            "text": "Coming soon.", 
            "title": "Fluent Transactions"
        }, 
        {
            "location": "/fluent/database/", 
            "text": "Fluent Database\n\n\nComing soon.\n\n\nConnection\n\n\nComing soon.\n\n\nLogger\n\n\nComing soon.", 
            "title": "Database"
        }, 
        {
            "location": "/fluent/database/#fluent-database", 
            "text": "Coming soon.", 
            "title": "Fluent Database"
        }, 
        {
            "location": "/fluent/database/#connection", 
            "text": "Coming soon.", 
            "title": "Connection"
        }, 
        {
            "location": "/fluent/database/#logger", 
            "text": "Coming soon.", 
            "title": "Logger"
        }, 
        {
            "location": "/http/getting-started/", 
            "text": "Getting Started with HTTP\n\n\nHTTP (\nvapor/http\n) is a non-blocking, event-driven HTTP library built on SwiftNIO. It makes working with SwiftNIO's HTTP handlers easy and offers higher-level functionality like media types, client upgrading, streaming bodies, and more. Creating an HTTP echo server takes just a few lines of code.\n\n\n\n\nTip\n\n\nIf you use Vapor, most of HTTP's APIs will be wrapped by more convenient methods. Usually the only HTTP type you\nwill interact with is the \nhttp\n property of \nRequest\n or \nResponse\n.\n\n\n\n\nVapor\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nHTTP\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n\n\n\n\n\n\nStandalone\n\n\nThe HTTP package is lightweight, pure Swift, and only depends on SwiftNIO. This means it can be used as an HTTP framework in any Swift project\neven one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/http.git\n,\n \nfrom\n:\n \n3.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nHTTP\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport HTTP\n to access the APIs.\n\n\nThe rest of this guide will give you an overview of what is available in the HTTP package. As always, feel free to visit the \nAPI docs\n for more in-depth information.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/http/getting-started/#getting-started-with-http", 
            "text": "HTTP ( vapor/http ) is a non-blocking, event-driven HTTP library built on SwiftNIO. It makes working with SwiftNIO's HTTP handlers easy and offers higher-level functionality like media types, client upgrading, streaming bodies, and more. Creating an HTTP echo server takes just a few lines of code.   Tip  If you use Vapor, most of HTTP's APIs will be wrapped by more convenient methods. Usually the only HTTP type you\nwill interact with is the  http  property of  Request  or  Response .", 
            "title": "Getting Started with HTTP"
        }, 
        {
            "location": "/http/getting-started/#vapor", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  HTTP  APIs when you import  Vapor .  import   Vapor", 
            "title": "Vapor"
        }, 
        {
            "location": "/http/getting-started/#standalone", 
            "text": "The HTTP package is lightweight, pure Swift, and only depends on SwiftNIO. This means it can be used as an HTTP framework in any Swift project even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/http.git ,   from :   3.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ HTTP ,   ...   ]) \n     ]  )   Use  import HTTP  to access the APIs.  The rest of this guide will give you an overview of what is available in the HTTP package. As always, feel free to visit the  API docs  for more in-depth information.", 
            "title": "Standalone"
        }, 
        {
            "location": "/http/client/", 
            "text": "Using HTTPClient\n\n\nHTTP clients send requests to remote HTTP servers which then generate and return responses. HTTP clients are usually only active for a matter of seconds to minutes and may send one or more requests. The \nHTTPClient\n type is what powers Vapor's higher-level client. This short guide will show you how to send HTTP requests to servers manually.\n\n\n\n\nTip\n\n\nIf you are using Vapor, you probably don't need to use HTTP's APIs directly. Refer to \nVapor \n Client\n for the more convenient APIs.\n\n\n\n\nFor this example, we will fetch Vapor's homepage. The first step is to create a connected HTTP client. Use the static \nconnect(...)\n method to do this.\n\n\n// Connect a new client to the supplied hostname.\n\n\nlet\n \nclient\n \n=\n \ntry\n \nHTTPClient\n.\nconnect\n(\nhostname\n:\n \nvapor.codes\n,\n \non\n:\n \n...).\nwait\n()\n\n\nprint\n(\nclient\n)\n \n// HTTPClient\n\n\n// Create an HTTP request: GET /\n\n\nlet\n \nhttpReq\n \n=\n \nHTTPRequest\n(\nmethod\n:\n \n.\nGET\n,\n \nurl\n:\n \n/\n)\n\n\n// Send the HTTP request, fetching a response\n\n\nlet\n \nhttpRes\n \n=\n \ntry\n \nclient\n.\nsend\n(\nhttpReq\n).\nwait\n()\n\n\nprint\n(\nhttpRes\n)\n \n// HTTPResponse\n\n\n\n\n\n\nTake note that we are passing the \nhostname\n. This is different from a full URL. You can use \nURL\n and \nURLComponents\n from Foundation to parse out a hostname. Vapor's convenience APIs do this automatically.\n\n\n\n\nWarning\n\n\nThis guide assumes you are on the main thread. Don't use \nwait()\n if you are inside of a route closure. See \nAsync \n Overview\n for more information.\n\n\n\n\nAfter we have a connected HTTP client, we can send an \nHTTPRequest\n using \nsend(...)\n. This will return an  \nHTTPResponse\n containing the headers and body sent back from the server. See \nHTTP \n Message\n for more information on HTTP messages. \n\n\nAPI Docs\n\n\nThat's it! Congratulations on making your first HTTP request. Check out the \nAPI docs\n for more in-depth information about all of the available parameters and methods.", 
            "title": "Client"
        }, 
        {
            "location": "/http/client/#using-httpclient", 
            "text": "HTTP clients send requests to remote HTTP servers which then generate and return responses. HTTP clients are usually only active for a matter of seconds to minutes and may send one or more requests. The  HTTPClient  type is what powers Vapor's higher-level client. This short guide will show you how to send HTTP requests to servers manually.   Tip  If you are using Vapor, you probably don't need to use HTTP's APIs directly. Refer to  Vapor   Client  for the more convenient APIs.   For this example, we will fetch Vapor's homepage. The first step is to create a connected HTTP client. Use the static  connect(...)  method to do this.  // Connect a new client to the supplied hostname.  let   client   =   try   HTTPClient . connect ( hostname :   vapor.codes ,   on :   ...). wait ()  print ( client )   // HTTPClient  // Create an HTTP request: GET /  let   httpReq   =   HTTPRequest ( method :   . GET ,   url :   / )  // Send the HTTP request, fetching a response  let   httpRes   =   try   client . send ( httpReq ). wait ()  print ( httpRes )   // HTTPResponse   Take note that we are passing the  hostname . This is different from a full URL. You can use  URL  and  URLComponents  from Foundation to parse out a hostname. Vapor's convenience APIs do this automatically.   Warning  This guide assumes you are on the main thread. Don't use  wait()  if you are inside of a route closure. See  Async   Overview  for more information.   After we have a connected HTTP client, we can send an  HTTPRequest  using  send(...) . This will return an   HTTPResponse  containing the headers and body sent back from the server. See  HTTP   Message  for more information on HTTP messages.", 
            "title": "Using HTTPClient"
        }, 
        {
            "location": "/http/client/#api-docs", 
            "text": "That's it! Congratulations on making your first HTTP request. Check out the  API docs  for more in-depth information about all of the available parameters and methods.", 
            "title": "API Docs"
        }, 
        {
            "location": "/http/server/", 
            "text": "Using HTTPServer\n\n\nHTTP servers respond to incoming \nHTTPRequests\n with \nHTTPResponses\n. The \nHTTPServer\n type is what powers Vapor's higher-level server. This short guide will show you how to set up your own HTTP server manually.\n\n\n\n\nTip\n\n\nIf you are using Vapor, you probably don't need to use HTTP's APIs directly. Refer to \nVapor \n Server\n for the more convenient APIs.\n\n\n\n\nResponder\n\n\nCreating an HTTP server is easy, and only takes a few lines of code. The first step is to create an \nHTTPServerResponder\n. This will be directly responsible for generating responses to incoming requests.\n\n\nLet's create a simple responder that will echo the request's content.\n\n\n/// Echoes the request as a response.\n\n\nstruct\n \nEchoResponder\n:\n \nHTTPServerResponder\n \n{\n\n    \n/// See `HTTPServerResponder`.\n\n    \nfunc\n \nrespond\n(\nto\n \nreq\n:\n \nHTTPRequest\n,\n \non\n \nworker\n:\n \nWorker\n)\n \n-\n \nFuture\nHTTPResponse\n \n{\n\n        \n// Create an HTTPResponse with the same body as the HTTPRequest\n\n        \nlet\n \nres\n \n=\n \nHTTPResponse\n(\nbody\n:\n \nreq\n.\nbody\n)\n\n        \n// We don\nt need to do any async work here, we can just\n\n        \n// se the Worker\ns event-loop to create a succeeded future.\n\n        \nreturn\n \nworker\n.\neventLoop\n.\nnewSucceededFuture\n(\nresult\n:\n \nres\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nStart\n\n\nNow that we have a responder, we can create our \nHTTPServer\n. We just need to choose a hostname and port for the server to bind to. In this example, we will bind to \nhttp://localhost:8123\n.\n\n\n// Create an EventLoopGroup with an appropriate number\n\n\n// of threads for the system we are running on.\n\n\nlet\n \ngroup\n \n=\n \nMultiThreadedEventLoopGroup\n(\nnumThreads\n:\n \nSystem\n.\ncoreCount\n)\n\n\n// Make sure to shutdown the group when the application exits.\n\n\ndefer\n \n{\n \ntry\n!\n \ngroup\n.\nsyncShutdownGracefully\n()\n \n}\n\n\n\n// Start an HTTPServer using our EchoResponder\n\n\n// We are fine to use `wait()` here since we are on the main thread.\n\n\nlet\n \nserver\n \n=\n \ntry\n \nHTTPServer\n.\nstart\n(\n\n    \nhostname\n:\n \nlocalhost\n,\n \n    \nport\n:\n \n8123\n,\n \n    \nresponder\n:\n \nEchoResponder\n(),\n \n    \non\n:\n \ngroup\n\n\n).\nwait\n()\n\n\n\n// Wait for the server to close (indefinitely).\n\n\ntry\n \nserver\n.\nonClose\n.\nwait\n()\n\n\n\n\n\n\nThe static \nstart(...)\n method creates and returns a new \nHTTPServer\n asynchronously. The future will be completed when the server has finished booting succesfully, or it will contain an error if something went wrong.\n\n\nOnce the start future is complete, our server is running. By waiting for the server's \nonClose\n future to complete, we can keep our application alive until the server closes. Normally the server will not close itself--it will just run indefinitely. However if \nserver.close()\n is ever called, the application can exit gracefully.\n\n\nAPI Docs\n\n\nThat's it! Congratulations on making your first HTTP server and responder. Check out the \nAPI docs\n for more in-depth information about all of the available parameters and methods.", 
            "title": "Server"
        }, 
        {
            "location": "/http/server/#using-httpserver", 
            "text": "HTTP servers respond to incoming  HTTPRequests  with  HTTPResponses . The  HTTPServer  type is what powers Vapor's higher-level server. This short guide will show you how to set up your own HTTP server manually.   Tip  If you are using Vapor, you probably don't need to use HTTP's APIs directly. Refer to  Vapor   Server  for the more convenient APIs.", 
            "title": "Using HTTPServer"
        }, 
        {
            "location": "/http/server/#responder", 
            "text": "Creating an HTTP server is easy, and only takes a few lines of code. The first step is to create an  HTTPServerResponder . This will be directly responsible for generating responses to incoming requests.  Let's create a simple responder that will echo the request's content.  /// Echoes the request as a response.  struct   EchoResponder :   HTTPServerResponder   { \n     /// See `HTTPServerResponder`. \n     func   respond ( to   req :   HTTPRequest ,   on   worker :   Worker )   -   Future HTTPResponse   { \n         // Create an HTTPResponse with the same body as the HTTPRequest \n         let   res   =   HTTPResponse ( body :   req . body ) \n         // We don t need to do any async work here, we can just \n         // se the Worker s event-loop to create a succeeded future. \n         return   worker . eventLoop . newSucceededFuture ( result :   res ) \n     }  }", 
            "title": "Responder"
        }, 
        {
            "location": "/http/server/#start", 
            "text": "Now that we have a responder, we can create our  HTTPServer . We just need to choose a hostname and port for the server to bind to. In this example, we will bind to  http://localhost:8123 .  // Create an EventLoopGroup with an appropriate number  // of threads for the system we are running on.  let   group   =   MultiThreadedEventLoopGroup ( numThreads :   System . coreCount )  // Make sure to shutdown the group when the application exits.  defer   {   try !   group . syncShutdownGracefully ()   }  // Start an HTTPServer using our EchoResponder  // We are fine to use `wait()` here since we are on the main thread.  let   server   =   try   HTTPServer . start ( \n     hostname :   localhost ,  \n     port :   8123 ,  \n     responder :   EchoResponder (),  \n     on :   group  ). wait ()  // Wait for the server to close (indefinitely).  try   server . onClose . wait ()   The static  start(...)  method creates and returns a new  HTTPServer  asynchronously. The future will be completed when the server has finished booting succesfully, or it will contain an error if something went wrong.  Once the start future is complete, our server is running. By waiting for the server's  onClose  future to complete, we can keep our application alive until the server closes. Normally the server will not close itself--it will just run indefinitely. However if  server.close()  is ever called, the application can exit gracefully.", 
            "title": "Start"
        }, 
        {
            "location": "/http/server/#api-docs", 
            "text": "That's it! Congratulations on making your first HTTP server and responder. Check out the  API docs  for more in-depth information about all of the available parameters and methods.", 
            "title": "API Docs"
        }, 
        {
            "location": "/http/message/", 
            "text": "Using HTTP Message\n\n\nThere are two types of HTTP messages, \nHTTPRequest\n and \nHTTPResponse\n. For the most part they are very similar, but there are a couple of differences. \n\n\nRequest\n\n\nHTTP requests are sent by clients to a server and they should always receive exactly one HTTP response. HTTP requests contain two unique fields over a standard HTTP message:\n\n\n\n\nmethod\n\n\nurl\n\n\n\n\nThe method and URL define what content on the server is being requested.\n\n\n/// GET /hello\n\n\nlet\n \nhttpReq\n \n=\n \nHTTPRequest\n(\nmethod\n:\n \n.\nGET\n,\n \nurl\n:\n \n/hello\n)\n\n\n\n\n\n\nYou can define these when initializing an HTTP request, or set them later if the request is mutable.\n\n\nvar\n \nhttpReq\n:\n \nHTTPRequest\n \n=\n \n...\n\n\nhttpReq\n.\nmethod\n \n=\n \n.\nPOST\n\n\nhttpReq\n.\nurl\n \n=\n \nURL\n(...)\n\n\n\n\n\n\nYou can use Foundation's \nURLComponents\n to create \nURL\ns from their base components. HTTP request also has a property \nurlString\n that you can use to set a custom URL \nString\n manually, without going through \nURL\n.\n\n\nHere is what a serialized HTTP request looks like. This one is querying \n/hello\n.\n\n\nGET\n \n/hello\n \nHTTP\n/\n1.1\n\n\nContent-Length\n:\n \n0\n\n\n\n\n\n\nResponse\n\n\nHTTP responses are generated by servers in response to an HTTP request. HTTP response only has one unique field over general HTTP messages:\n\n\n\n\nstatus\n\n\n\n\nThe HTTP status is used to inform the client of any errors. The status consists of a status code and a reason. The code is always a three digit number and the reason is a short string explaining the code. You can see all of the status codes on \nhttpstatuses.com\n.\n\n\nlet\n \nhttpRes\n \n=\n \nHTTPResponse\n(\nstatus\n:\n \n.\nok\n,\n \nbody\n:\n \nhello\n)\n\n\n\n\n\n\nAll of the commonly used HTTP statuses will have pre-defined values you can use, like \n.ok\n for \n200 OK\n. You can also define your own custom status codes.\n\n\nYou can define the status when initializing an HTTP response, or set it later if the response is mutable.\n\n\nvar\n \nhttpRes\n:\n \nHTTPResponse\n \n=\n \n...\n\n\nhttpRes\n.\nstatus\n \n=\n \n.\nnotFound\n\n\n\n\n\n\nHere is an example of a serialized HTTP response.\n\n\nHTTP\n/\n1.1\n \n200\n \nOK\n\n\nContent-Length\n:\n \n5\n\n\nContent-Type\n:\n \ntext/plain\n\n\nhello\n\n\n\n\n\nHeaders\n\n\nEvery HTTP message has a collection of headers. Headers contain metadata about the message and help to explain what is in the message's body. \n\n\nContent-Length: 5\n\n\nContent-Type: text/plain\n\n\n\n\n\n\nThere must be at least a \n\"Content-Length\"\n or \n\"Transfer-Encoding\"\n header to define how long the message's body is. There is almost always a \n\"Content-Type\"\n header that explains what \ntype\n of data the body contains. There are many other common headers such as \n\"Date\"\n which specifies when the message was created, and more.\n\n\nYou can access an HTTP message's headers using the \nheaders\n property.\n\n\nvar\n \nmessage\n:\n \nHTTPMessage\n \n...\n\n\nmessage\n.\nheaders\n.\nfirstValue\n(\nfor\n:\n \n.\ncontentLength\n)\n \n// 5\n\n\n\n\n\n\nIf you are interacting with common HTTP headers, you can use the convenience HTTP names instead of a raw \nString\n.\n\n\nBody\n\n\nHTTP messages can have an \nHTTPBody\n containing arbitrary data. This data can be either static or streaming and can be in whatever format you want. Use the \ncontentType\n header to describe the type of data.\n\n\nvar\n \nmessage\n:\n \nHTTPMessage\n \n=\n \n...\n\n\nmessage\n.\nbody\n \n=\n \nHTTPBody\n(\nstring\n:\n \nHello, world!\n)\n\n\nmessage\n.\ncontentType\n \n=\n \n.\nplainText\n\n\n\n\n\n\n\n\nTip\n\n\nSetting the \nbody\n property will automatically update the \n\"Content-Length\"\n or \n\"Transfer-Encoding\"\n headers if required.\n\n\n\n\nvar\n \nmessage\n:\n \nHTTPMessage\n \n=\n \n...\n\n\nmessage\n.\nbody\n \n=\n \nHTTPBody\n(\nstring\n:\n \n\n\n{\nmessage\n: \nHello\n,\n \nworld\n!\n}\n\n\n)\n\n\nmessage\n.\ncontentType\n \n=\n \n.\njson\n\n\n\n\n\n\nCodable\n\n\nTwo protocols are defined for making it easy to use \nCodable\n with HTTP:\n\n\n\n\nHTTPMessageEncoder\n\n\nHTTPMessageDecoder\n\n\n\n\nThese two coders allow you to encode and decode your custom \nCodable\n types into an HTTP body, setting the appropriate content type headers.\n\n\nBy default, HTTP provides conformance for \nJSONEncoder\n and \nJSONDecoder\n, but Vapor includes coders for many more types.\n\n\nHere is an example of encoding a \nCodable\n struct to an HTTP response.\n\n\nstruct\n \nGreeting\n:\n \nCodable\n \n{\n\n    \nvar\n \nmessage\n:\n \nString\n\n\n}\n\n\n// Create an instance of Greeting\n\n\nlet\n \ngreeting\n \n=\n \nGreeting\n(\nmessage\n:\n \nHello, world!\n)\n\n\n// Create a 200 OK response\n\n\nvar\n \nhttpRes\n \n=\n \nHTTPResponse\n(\nstatus\n:\n \n.\nok\n)\n\n\n// Encode the greeting to the response\n\n\ntry\n \nJSONEncoder\n().\nencode\n(\ngreeting\n,\n \nto\n:\n \nhttpRes\n,\n \non\n:\n \n...)\n\n\n\n\n\n\nAPI Docs\n\n\nCheck out the \nAPI docs\n for more in-depth information about all of the methods.", 
            "title": "Message"
        }, 
        {
            "location": "/http/message/#using-http-message", 
            "text": "There are two types of HTTP messages,  HTTPRequest  and  HTTPResponse . For the most part they are very similar, but there are a couple of differences.", 
            "title": "Using HTTP Message"
        }, 
        {
            "location": "/http/message/#request", 
            "text": "HTTP requests are sent by clients to a server and they should always receive exactly one HTTP response. HTTP requests contain two unique fields over a standard HTTP message:   method  url   The method and URL define what content on the server is being requested.  /// GET /hello  let   httpReq   =   HTTPRequest ( method :   . GET ,   url :   /hello )   You can define these when initializing an HTTP request, or set them later if the request is mutable.  var   httpReq :   HTTPRequest   =   ...  httpReq . method   =   . POST  httpReq . url   =   URL (...)   You can use Foundation's  URLComponents  to create  URL s from their base components. HTTP request also has a property  urlString  that you can use to set a custom URL  String  manually, without going through  URL .  Here is what a serialized HTTP request looks like. This one is querying  /hello .  GET   /hello   HTTP / 1.1  Content-Length :   0", 
            "title": "Request"
        }, 
        {
            "location": "/http/message/#response", 
            "text": "HTTP responses are generated by servers in response to an HTTP request. HTTP response only has one unique field over general HTTP messages:   status   The HTTP status is used to inform the client of any errors. The status consists of a status code and a reason. The code is always a three digit number and the reason is a short string explaining the code. You can see all of the status codes on  httpstatuses.com .  let   httpRes   =   HTTPResponse ( status :   . ok ,   body :   hello )   All of the commonly used HTTP statuses will have pre-defined values you can use, like  .ok  for  200 OK . You can also define your own custom status codes.  You can define the status when initializing an HTTP response, or set it later if the response is mutable.  var   httpRes :   HTTPResponse   =   ...  httpRes . status   =   . notFound   Here is an example of a serialized HTTP response.  HTTP / 1.1   200   OK  Content-Length :   5  Content-Type :   text/plain \n\nhello", 
            "title": "Response"
        }, 
        {
            "location": "/http/message/#headers", 
            "text": "Every HTTP message has a collection of headers. Headers contain metadata about the message and help to explain what is in the message's body.   Content-Length: 5  Content-Type: text/plain   There must be at least a  \"Content-Length\"  or  \"Transfer-Encoding\"  header to define how long the message's body is. There is almost always a  \"Content-Type\"  header that explains what  type  of data the body contains. There are many other common headers such as  \"Date\"  which specifies when the message was created, and more.  You can access an HTTP message's headers using the  headers  property.  var   message :   HTTPMessage   ...  message . headers . firstValue ( for :   . contentLength )   // 5   If you are interacting with common HTTP headers, you can use the convenience HTTP names instead of a raw  String .", 
            "title": "Headers"
        }, 
        {
            "location": "/http/message/#body", 
            "text": "HTTP messages can have an  HTTPBody  containing arbitrary data. This data can be either static or streaming and can be in whatever format you want. Use the  contentType  header to describe the type of data.  var   message :   HTTPMessage   =   ...  message . body   =   HTTPBody ( string :   Hello, world! )  message . contentType   =   . plainText    Tip  Setting the  body  property will automatically update the  \"Content-Length\"  or  \"Transfer-Encoding\"  headers if required.   var   message :   HTTPMessage   =   ...  message . body   =   HTTPBody ( string :    { message :  Hello ,   world ! }  )  message . contentType   =   . json", 
            "title": "Body"
        }, 
        {
            "location": "/http/message/#codable", 
            "text": "Two protocols are defined for making it easy to use  Codable  with HTTP:   HTTPMessageEncoder  HTTPMessageDecoder   These two coders allow you to encode and decode your custom  Codable  types into an HTTP body, setting the appropriate content type headers.  By default, HTTP provides conformance for  JSONEncoder  and  JSONDecoder , but Vapor includes coders for many more types.  Here is an example of encoding a  Codable  struct to an HTTP response.  struct   Greeting :   Codable   { \n     var   message :   String  }  // Create an instance of Greeting  let   greeting   =   Greeting ( message :   Hello, world! )  // Create a 200 OK response  var   httpRes   =   HTTPResponse ( status :   . ok )  // Encode the greeting to the response  try   JSONEncoder (). encode ( greeting ,   to :   httpRes ,   on :   ...)", 
            "title": "Codable"
        }, 
        {
            "location": "/http/message/#api-docs", 
            "text": "Check out the  API docs  for more in-depth information about all of the methods.", 
            "title": "API Docs"
        }, 
        {
            "location": "/leaf/getting-started/", 
            "text": "Warning\n\n\nLeaf 3.0 is still in beta. Some documentation may be missing or out of date.\n\n\n\n\nLeaf\n\n\nLeaf is a templating language that integrates with Futures, Reactive Streams and Codable. This section outlines how to import the Leaf package into a Vapor project.\n\n\nExample Folder Structure\n\n\nHello\n\u251c\u2500\u2500 Package.resolved\n\u251c\u2500\u2500 Package.swift\n\u251c\u2500\u2500 Public\n\u251c\u2500\u2500 Resources\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 Views\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 hello.leaf\n\u251c\u2500\u2500 Public\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 images (images resources)\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 styles (css resources)\n\u251c\u2500\u2500 Sources\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 App\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 boot.swift\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 configure.swift\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 routes.swift\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 Run\n\u2502\u00a0\u00a0     \u2514\u2500\u2500 main.swift\n\u251c\u2500\u2500 Tests\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 AppTests\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 AppTests.swift\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 LinuxMain.swift\n\u2514\u2500\u2500 LICENSE\n\n\n\n\n\nAdding Leaf to your project\n\n\nThe easiest way to use Leaf with Vapor is to include the Leaf repository as a dependency in Package.swift:\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nproject1\n,\n\n    \ndependencies\n:\n \n[\n\n        \n// \ud83d\udca7 A server-side Swift web framework.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/vapor.git\n,\n \n.\nbranch\n(\nbeta\n)),\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/leaf.git\n,\n \n.\nbranch\n(\nbeta\n)),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\n\n            \nname\n:\n \nApp\n,\n\n            \ndependencies\n:\n \n[\nVapor\n,\n \nLeaf\n]\n\n        \n),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nThe Leaf package adds Leaf to your project, but to configure it for use you must modify configure.swift:\n\n\n\n\nAdd \nimport Leaf\n to the top of the file so that Leaf is available to use. You will also need to add this to any file that will render templates.\n\n\nAdd \ntry services.register(LeafProvider())\n to the \nconfigure()\n function so that routes may render Leaf templates as needed.\n\n\n\n\nSyntax Highlighting\n\n\nYou may also wish to install one these third-party packages that provide support for syntax highlighting in Leaf templates.\n\n\nAtom\n\n\nlanguage-leaf\n by ButkiewiczP\n\n\nXcode\n\n\nIt is not currently possible to implement Leaf Syntax Highlighting in Xcode, however, using Xcode's HTML Syntax Coloring can help a bit. Select one or more Leaf files and then choose Editor \n Syntax Coloring \n HTML.  Your selected Leaf files will now use Xcode's HTML Syntax Coloring.  Unfortunately the usefulness of this is limited because this association will be removed when \nvapor xcode\n is run.\n\n\nThere appears to be a way to \nmake Xcode file associations persist\n but that requires a bit more kung-fu.\n\n\nVS Code\n\n\nhtml-leaf\n by FranciscoAmado\n\n\nCLion \n AppCode\n\n\nSome preliminary work has been done to implement a Leaf Plugin for CLion \n AppCode but lack of skill and interest in Java has slowed progress! If you have IntelliJ SDK experience and want to help with this, message Tom Holland on \nVapor Slack", 
            "title": "Getting Started"
        }, 
        {
            "location": "/leaf/getting-started/#leaf", 
            "text": "Leaf is a templating language that integrates with Futures, Reactive Streams and Codable. This section outlines how to import the Leaf package into a Vapor project.", 
            "title": "Leaf"
        }, 
        {
            "location": "/leaf/getting-started/#example-folder-structure", 
            "text": "Hello\n\u251c\u2500\u2500 Package.resolved\n\u251c\u2500\u2500 Package.swift\n\u251c\u2500\u2500 Public\n\u251c\u2500\u2500 Resources\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 Views\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 hello.leaf\n\u251c\u2500\u2500 Public\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 images (images resources)\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 styles (css resources)\n\u251c\u2500\u2500 Sources\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 App\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 boot.swift\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 configure.swift\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 routes.swift\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 Run\n\u2502\u00a0\u00a0     \u2514\u2500\u2500 main.swift\n\u251c\u2500\u2500 Tests\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 AppTests\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 AppTests.swift\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 LinuxMain.swift\n\u2514\u2500\u2500 LICENSE", 
            "title": "Example Folder Structure"
        }, 
        {
            "location": "/leaf/getting-started/#adding-leaf-to-your-project", 
            "text": "The easiest way to use Leaf with Vapor is to include the Leaf repository as a dependency in Package.swift:  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   project1 , \n     dependencies :   [ \n         // \ud83d\udca7 A server-side Swift web framework. \n         . package ( url :   https://github.com/vapor/vapor.git ,   . branch ( beta )), \n         . package ( url :   https://github.com/vapor/leaf.git ,   . branch ( beta )), \n     ], \n     targets :   [ \n         . target ( \n             name :   App , \n             dependencies :   [ Vapor ,   Leaf ] \n         ), \n         . target ( name :   Run ,   dependencies :   [ App ]), \n         . testTarget ( name :   AppTests ,   dependencies :   [ App ]), \n     ]  )   The Leaf package adds Leaf to your project, but to configure it for use you must modify configure.swift:   Add  import Leaf  to the top of the file so that Leaf is available to use. You will also need to add this to any file that will render templates.  Add  try services.register(LeafProvider())  to the  configure()  function so that routes may render Leaf templates as needed.", 
            "title": "Adding Leaf to your project"
        }, 
        {
            "location": "/leaf/getting-started/#syntax-highlighting", 
            "text": "You may also wish to install one these third-party packages that provide support for syntax highlighting in Leaf templates.", 
            "title": "Syntax Highlighting"
        }, 
        {
            "location": "/leaf/getting-started/#atom", 
            "text": "language-leaf  by ButkiewiczP", 
            "title": "Atom"
        }, 
        {
            "location": "/leaf/getting-started/#xcode", 
            "text": "It is not currently possible to implement Leaf Syntax Highlighting in Xcode, however, using Xcode's HTML Syntax Coloring can help a bit. Select one or more Leaf files and then choose Editor   Syntax Coloring   HTML.  Your selected Leaf files will now use Xcode's HTML Syntax Coloring.  Unfortunately the usefulness of this is limited because this association will be removed when  vapor xcode  is run.  There appears to be a way to  make Xcode file associations persist  but that requires a bit more kung-fu.", 
            "title": "Xcode"
        }, 
        {
            "location": "/leaf/getting-started/#vs-code", 
            "text": "html-leaf  by FranciscoAmado", 
            "title": "VS Code"
        }, 
        {
            "location": "/leaf/getting-started/#clion-appcode", 
            "text": "Some preliminary work has been done to implement a Leaf Plugin for CLion   AppCode but lack of skill and interest in Java has slowed progress! If you have IntelliJ SDK experience and want to help with this, message Tom Holland on  Vapor Slack", 
            "title": "CLion &amp; AppCode"
        }, 
        {
            "location": "/leaf/basics/", 
            "text": "Basics\n\n\nWelcome to Leaf. Leaf's goal is to be a simple templating language that can make generating views easier. There are plenty of great templating languages, so use what's best for you \u2013 maybe that's Leaf! The goals of Leaf are:\n\n\n\n\nSmall set of strictly enforced rules\n\n\nConsistency\n\n\nParser first mentality\n\n\nExtensibility\n\n\nAsynchronous and reactive\n\n\n\n\nRendering a template\n\n\nOnce you have Leaf installed, you should create a directory called \u201cResources\u201d inside your project folder, and inside that create another directory called \u201cViews\u201d. This Resources/Views directory is the default location for Leaf templates, although you can change it if you want.\n\n\nFirstly, import Leaf to routes.swift\n\n\nimport\n \nLeaf\n\n\n\n\n\n\nThen, to render a basic Leaf template from a route, add this code:\n\n\nrouter\n.\nget\n \n{\n \nreq\n \n-\n \nFuture\nView\n \nin\n\n    \nlet\n \nleaf\n \n=\n \ntry\n \nreq\n.\nmake\n(\nLeafRenderer\n.\nself\n)\n\n    \nlet\n \ncontext\n \n=\n \n[\nString\n:\n \nString\n]()\n\n    \nreturn\n \ntry\n \nleaf\n.\nrender\n(\nhome\n,\n \ncontext\n)\n\n\n}\n\n\n\n\n\n\nThat will load home.leaf in the Resources/Views directory and render it. The \ncontext\n dictionary is there to let you provide custom data to render inside the template, but you might find it easier to use codable structs instead because they provide extra type safety. For example:\n\n\nstruct\n \nHomePage\n:\n \nCodable\n \n{\n\n    \nvar\n \ntitle\n:\n \nString\n\n    \nvar\n \ncontent\n:\n \nString\n\n\n}\n\n\n\n\n\n\nAsync\n\n\nLeaf's engine is completely reactive, supporting both streams and futures. One of the only ones of its kind.\n\n\nWhen working with Future results, simply pass the \nFuture\n in your template context.\nStreams that carry an encodable type need to be encoded before they're usable within Leaf.\n\n\nstruct\n \nProfile\n:\n \nCodable\n \n{\n\n    \nvar\n \nfriends\n:\n \nEncodableStream\n\n    \nvar\n \ncurrentUser\n:\n \nFuture\nUser\n\n\n}\n\n\n\n\n\n\nIn the above context, the \ncurrentUser\n variable in Leaf will behave as being a \nUser\n type. Leaf will not read the user Future if it's not used during rendering.\n\n\nEncodableStream\n will behave as an array of LeafData, only with lower memory impact and better performance. It is recommended to use \nEncodableStream\n for (large) database queries.\n\n\nYour name is #(currentUser.name).\n\n#for(friend in friends) {\n    #(friend.name) is a friend of you.\n}\n\n\n\n\n\nTemplate syntax\n\n\nStructure\n\n\nLeaf tags are made up of four elements:\n\n\n\n\nToken: \n#\n is the token\n\n\nName: A \nstring\n that identifies the tag\n\n\nParameter List: \n()\n May accept 0 or more arguments\n\n\nBody (optional): \n{}\n Must be separated from the parameter list by a space\n\n\n\n\nThere can be many different usages of these four elements depending on the tag's implementation. Let's look at a few examples of how Leaf's built-in tags might be used:\n\n\n\n\n#()\n\n\n#(variable)\n\n\n#embed(\"template\")\n\n\n#set(\"title\") { Welcome to Vapor }\n\n\n#count(friends)\n\n\n#for(friend in friends) { \nli\n#(friend.name)\n/li\n }\n\n\n\n\nWorking with context\n\n\nIn our Swift example from earlier, we used an empty \n[String: String]\n dictionary for context, which passes no custom data to Leaf. To try rendering content, use this code instead:\n\n\nlet\n \ncontext\n \n=\n \n[\ntitle\n:\n \nWelcome\n,\n \nmessage\n:\n \nVapor and Leaf work hand in hand\n]\n\n\nreturn\n \ntry\n \nleaf\n.\nmake\n(\nhome\n,\n \ncontext\n)\n\n\n\n\n\n\nThat will expose \ntitle\n and \nmessage\n to our Leaf template, which can then be used inside tags. For example:\n\n\nh1\n#(title)\n/h1\n\n\np\n#(message)\n/p\n\n\n\n\n\n\nChecking conditions\n\n\nLeaf is able to evaluate a range of conditions using its \n#if\n tag. For example, if you provide a variable it will check that variable exists in its context:\n\n\n#if(title) {\n    The title is #(title)\n} else {\n    No title was provided.\n}\n\n\n\n\n\nYou can also write comparisons, for example:\n\n\n#if(title == \nWelcome\n) {\n    This is a friendly web page.\n} else {\n    No strangers allowed!\n}\n\n\n\n\n\nIf you want to use another tag as part of your condition, you should omit the \n#\n for the inner tag. For example:\n\n\n#if(lowercase(title) == \nwelcome\n) {\n    This is a friendly web page.\n} else {\n    No strangers allowed!\n}\n\n\n\n\n\nLoops\n\n\nIf you provide an array of items, Leaf can loop over them and let you manipulate each item individually using its \n#for\n tag. For example, we could update our Swift code to provide a list of names in a team:\n\n\nlet\n \ncontext\n \n=\n \n[\nteam\n:\n \n[\nMalcolm\n,\n \nKaylee\n,\n \nJayne\n]]\n\n\n\n\n\n\nWe could then loop over them in Leaf like this:\n\n\n#for(name in team) {\n    \np\n#(name) is in the team.\n/p\n\n}\n\n\n\n\n\nLeaf provides some extra variables inside a \n#for\n loop to give you more information about the loop's progress:\n\n\n\n\nThe \nloop.isFirst\n variable is true when the current iteration is the first one.\n\n\nThe \nloop.isLast\n variable is true when it's the last iteration.\n\n\nThe \nloop.index\n variable will be set to the number of the current iteration, counting from 0.\n\n\n\n\nHere's how we could use a loop variable to print just the first name in our array:\n\n\n#for(name in team) {\n    #if(isFirst) { \np\n#(name) is first!\n/p\n }\n}\n\n\n\n\n\nEmbedding templates\n\n\nLeaf\u2019s \n#embed\n tag allows you to copy the contents of one template into another. When use this, you should always omit the template file's .leaf extension.\n\n\nEmbedding is useful for copying in a standard piece of content, for example a page footer or advert code:\n\n\n#embed(\nfooter\n)\n\n\n\n\n\nThis tag is also useful for building one template on top of another. For example, you might have a master.leaf file that includes all the code required to lay out your website \u2013\u00a0HTML structure, CSS and JavaScript \u2013\u00a0with some gaps in place that represent where page content varies.\n\n\nUsing this approach, you would construct a child template that fills in its unique content, then embeds the parent template that places the content appropriately.\n\n\nFor example, you might create a child.leaf template like this:\n\n\n#set(\nbody\n) {\n\np\nWelcome to Vapor!\n/p\n\n}\n\n#embed(\nmaster\n)\n\n\n\n\n\nThat configures one item of context, \nbody\n, but doesn\u2019t display it directly. Instead, it embeds master.leaf, which can render \nbody\n along with any other context variables passed in from Swift. For example, master.leaf might look like this:\n\n\nhtml\n\n\nhead\ntitle\n#(title)\n/title\n/head\n\n\nbody\n#get(body)\n/body\n\n\n/html\n\n\n\n\n\n\nWhen given the context \n[\"title\": \"Hi there!\"]\n, child.leaf will render as follows:\n\n\nhtml\n\n\nhead\ntitle\nHi there!\n/title\n/head\n\n\nbody\np\nWelcome to Vapor!\n/p\n/body\n\n\n/html\n\n\n\n\n\n\nOther tags\n\n\n#capitalize\n\n\nThe \n#capitalize\n tag uppercases the first letter of any string. For example, \u201ctaylor\u201d will become \u201cTaylor\u201d.\n\n\n#capitalize(name)\n\n\n\n\n\n#contains\n\n\nThe \n#contains\n tag accepts an array and a value as its two parameters, and returns true if the array in parameter one contains the value in parameter two. For example, given the array \nteam\n:\n\n\n#if(contains(team, \nJayne\n)) {\n    You\nre all set!\n} else {\n    You need someone to do PR.\n}\n\n\n\n\n\n#count\n\n\nThe \n#count\n tag returns the number of items in an array. For example:\n\n\nYour search matched #count(matches) pages.\n\n\n\n\n\n#lowercase\n\n\nThe \n#lowercase\n tag lowercases all letters in a string. For example, \u201cTaylor\u201d will become \u201ctaylor\u201d.\n\n\n#lowercase(name)\n\n\n\n\n\n#uppercase\n\n\nThe \n#uppercase\n tag uppercases all letters in a string. For example, \u201cTaylor\u201d will become \u201cTAYLOR\u201d.\n\n\n#uppercase(name)", 
            "title": "Basics"
        }, 
        {
            "location": "/leaf/basics/#basics", 
            "text": "Welcome to Leaf. Leaf's goal is to be a simple templating language that can make generating views easier. There are plenty of great templating languages, so use what's best for you \u2013 maybe that's Leaf! The goals of Leaf are:   Small set of strictly enforced rules  Consistency  Parser first mentality  Extensibility  Asynchronous and reactive", 
            "title": "Basics"
        }, 
        {
            "location": "/leaf/basics/#rendering-a-template", 
            "text": "Once you have Leaf installed, you should create a directory called \u201cResources\u201d inside your project folder, and inside that create another directory called \u201cViews\u201d. This Resources/Views directory is the default location for Leaf templates, although you can change it if you want.  Firstly, import Leaf to routes.swift  import   Leaf   Then, to render a basic Leaf template from a route, add this code:  router . get   {   req   -   Future View   in \n     let   leaf   =   try   req . make ( LeafRenderer . self ) \n     let   context   =   [ String :   String ]() \n     return   try   leaf . render ( home ,   context )  }   That will load home.leaf in the Resources/Views directory and render it. The  context  dictionary is there to let you provide custom data to render inside the template, but you might find it easier to use codable structs instead because they provide extra type safety. For example:  struct   HomePage :   Codable   { \n     var   title :   String \n     var   content :   String  }", 
            "title": "Rendering a template"
        }, 
        {
            "location": "/leaf/basics/#async", 
            "text": "Leaf's engine is completely reactive, supporting both streams and futures. One of the only ones of its kind.  When working with Future results, simply pass the  Future  in your template context.\nStreams that carry an encodable type need to be encoded before they're usable within Leaf.  struct   Profile :   Codable   { \n     var   friends :   EncodableStream \n     var   currentUser :   Future User  }   In the above context, the  currentUser  variable in Leaf will behave as being a  User  type. Leaf will not read the user Future if it's not used during rendering.  EncodableStream  will behave as an array of LeafData, only with lower memory impact and better performance. It is recommended to use  EncodableStream  for (large) database queries.  Your name is #(currentUser.name).\n\n#for(friend in friends) {\n    #(friend.name) is a friend of you.\n}", 
            "title": "Async"
        }, 
        {
            "location": "/leaf/basics/#template-syntax", 
            "text": "", 
            "title": "Template syntax"
        }, 
        {
            "location": "/leaf/basics/#structure", 
            "text": "Leaf tags are made up of four elements:   Token:  #  is the token  Name: A  string  that identifies the tag  Parameter List:  ()  May accept 0 or more arguments  Body (optional):  {}  Must be separated from the parameter list by a space   There can be many different usages of these four elements depending on the tag's implementation. Let's look at a few examples of how Leaf's built-in tags might be used:   #()  #(variable)  #embed(\"template\")  #set(\"title\") { Welcome to Vapor }  #count(friends)  #for(friend in friends) {  li #(friend.name) /li  }", 
            "title": "Structure"
        }, 
        {
            "location": "/leaf/basics/#working-with-context", 
            "text": "In our Swift example from earlier, we used an empty  [String: String]  dictionary for context, which passes no custom data to Leaf. To try rendering content, use this code instead:  let   context   =   [ title :   Welcome ,   message :   Vapor and Leaf work hand in hand ]  return   try   leaf . make ( home ,   context )   That will expose  title  and  message  to our Leaf template, which can then be used inside tags. For example:  h1 #(title) /h1  p #(message) /p", 
            "title": "Working with context"
        }, 
        {
            "location": "/leaf/basics/#checking-conditions", 
            "text": "Leaf is able to evaluate a range of conditions using its  #if  tag. For example, if you provide a variable it will check that variable exists in its context:  #if(title) {\n    The title is #(title)\n} else {\n    No title was provided.\n}  You can also write comparisons, for example:  #if(title ==  Welcome ) {\n    This is a friendly web page.\n} else {\n    No strangers allowed!\n}  If you want to use another tag as part of your condition, you should omit the  #  for the inner tag. For example:  #if(lowercase(title) ==  welcome ) {\n    This is a friendly web page.\n} else {\n    No strangers allowed!\n}", 
            "title": "Checking conditions"
        }, 
        {
            "location": "/leaf/basics/#loops", 
            "text": "If you provide an array of items, Leaf can loop over them and let you manipulate each item individually using its  #for  tag. For example, we could update our Swift code to provide a list of names in a team:  let   context   =   [ team :   [ Malcolm ,   Kaylee ,   Jayne ]]   We could then loop over them in Leaf like this:  #for(name in team) {\n     p #(name) is in the team. /p \n}  Leaf provides some extra variables inside a  #for  loop to give you more information about the loop's progress:   The  loop.isFirst  variable is true when the current iteration is the first one.  The  loop.isLast  variable is true when it's the last iteration.  The  loop.index  variable will be set to the number of the current iteration, counting from 0.   Here's how we could use a loop variable to print just the first name in our array:  #for(name in team) {\n    #if(isFirst) {  p #(name) is first! /p  }\n}", 
            "title": "Loops"
        }, 
        {
            "location": "/leaf/basics/#embedding-templates", 
            "text": "Leaf\u2019s  #embed  tag allows you to copy the contents of one template into another. When use this, you should always omit the template file's .leaf extension.  Embedding is useful for copying in a standard piece of content, for example a page footer or advert code:  #embed( footer )  This tag is also useful for building one template on top of another. For example, you might have a master.leaf file that includes all the code required to lay out your website \u2013\u00a0HTML structure, CSS and JavaScript \u2013\u00a0with some gaps in place that represent where page content varies.  Using this approach, you would construct a child template that fills in its unique content, then embeds the parent template that places the content appropriately.  For example, you might create a child.leaf template like this:  #set( body ) { p Welcome to Vapor! /p \n}\n\n#embed( master )  That configures one item of context,  body , but doesn\u2019t display it directly. Instead, it embeds master.leaf, which can render  body  along with any other context variables passed in from Swift. For example, master.leaf might look like this:  html  head title #(title) /title /head  body #get(body) /body  /html   When given the context  [\"title\": \"Hi there!\"] , child.leaf will render as follows:  html  head title Hi there! /title /head  body p Welcome to Vapor! /p /body  /html", 
            "title": "Embedding templates"
        }, 
        {
            "location": "/leaf/basics/#other-tags", 
            "text": "", 
            "title": "Other tags"
        }, 
        {
            "location": "/leaf/basics/#capitalize", 
            "text": "The  #capitalize  tag uppercases the first letter of any string. For example, \u201ctaylor\u201d will become \u201cTaylor\u201d.  #capitalize(name)", 
            "title": "#capitalize"
        }, 
        {
            "location": "/leaf/basics/#contains", 
            "text": "The  #contains  tag accepts an array and a value as its two parameters, and returns true if the array in parameter one contains the value in parameter two. For example, given the array  team :  #if(contains(team,  Jayne )) {\n    You re all set!\n} else {\n    You need someone to do PR.\n}", 
            "title": "#contains"
        }, 
        {
            "location": "/leaf/basics/#count", 
            "text": "The  #count  tag returns the number of items in an array. For example:  Your search matched #count(matches) pages.", 
            "title": "#count"
        }, 
        {
            "location": "/leaf/basics/#lowercase", 
            "text": "The  #lowercase  tag lowercases all letters in a string. For example, \u201cTaylor\u201d will become \u201ctaylor\u201d.  #lowercase(name)", 
            "title": "#lowercase"
        }, 
        {
            "location": "/leaf/basics/#uppercase", 
            "text": "The  #uppercase  tag uppercases all letters in a string. For example, \u201cTaylor\u201d will become \u201cTAYLOR\u201d.  #uppercase(name)", 
            "title": "#uppercase"
        }, 
        {
            "location": "/leaf/custom-tags/", 
            "text": "Custom Tags\n\n\nYou can extend Leaf to provide your own tags that add custom functionality. To demonstrate this, let's look at a basic example by recreating \n#uppercase\n together. This tag will take one argument, which is the string to uppercase.\n\n\nWhen working with custom tags, there are four important things to know:\n\n\n\n\nYou should call \nrequireParameterCount()\n with the number of parameters you expect to receive. This will throw an error if your tag is used incorrectly.\n\n\nIf you do or do not require a body, you should use either \nrequireBody()\n or \nrequireNoBody()\n. Again, this will throw an error if your tag is used incorrectly.\n\n\nYou can read individual parameters using the \nparameters\n array. Each parameter will be of type \nLeafData\n, which you can convert to concrete data types using properties such as \n.string\n, \n.dictionary\n, and so on.\n\n\nYou must return a \nFuture\nLeafData?\n containing what should be rendered. In the example below we wrap the resulting uppercase string in a \nLeafData\n string, then send that back wrapped in a future.\n\n\n\n\nHere\u2019s example code for a \nCustomUppercase\n Leaf tag:\n\n\nimport\n \nAsync\n\n\nimport\n \nLeaf\n\n\n\npublic\n \nfinal\n \nclass\n \nCustomUppercase\n:\n \nLeaf\n.\nLeafTag\n \n{\n\n    \npublic\n \ninit\n()\n \n{}\n\n    \npublic\n \nfunc\n \nrender\n(\nparsed\n:\n \nParsedTag\n,\n \ncontext\n:\n \nLeafContext\n,\n \nrenderer\n:\n \nLeafRenderer\n)\n \nthrows\n \n-\n \nFuture\nLeafData\n?\n \n{\n\n        \n// ensure we receive precisely one parameter\n\n        \ntry\n \nparsed\n.\nrequireParameterCount\n(\n1\n)\n\n\n        \n// pull out our lone parameter as a string then uppercase it, or use an empty string\n\n        \nlet\n \nstring\n \n=\n \nparsed\n.\nparameters\n[\n0\n].\nstring\n?.\nuppercased\n()\n \n??\n \n\n\n        \n// send it back wrapped in a LeafData\n\n        \nreturn\n \nFuture\n(.\nstring\n(\nstring\n))\n\n    \n}\n\n\n}\n\n\n\n\n\n\nWe can now register this Tag in our \nconfigure.swift\n file with:\n\n\nservices\n.\nregister\n \n{\n \ncontainer\n \n-\n \nLeafConfig\n \nin\n\n    \n// take a copy of Leaf\ns default tags\n\n    \nvar\n \ntags\n \n=\n \ndefaultTags\n\n\n    \n// add our custom tag\n\n    \ntags\n[\ncustomuppercase\n]\n \n=\n \nCustomUppercase\n()\n\n\n    \n// find the location of our Resources/Views directory\n\n    \nlet\n \ndirectoryConfig\n \n=\n \ntry\n \ncontainer\n.\nmake\n(\nDirectoryConfig\n.\nself\n,\n \nfor\n:\n \nLeafRenderer\n.\nself\n)\n\n    \nlet\n \nviewsDirectory\n \n=\n \ndirectoryConfig\n.\nworkDir\n \n+\n \nResources/Views\n\n\n    \n// put all that into a new Leaf configuration and return it\n\n    \nreturn\n \nLeafConfig\n(\ntags\n:\n \ntags\n,\n \nviewsDir\n:\n \nviewsDirectory\n)\n\n\n}\n\n\n\n\n\n\nOnce that is complete, you can use \n#customuppercase(some_variable)\n to run your custom code.\n\n\n\n\nNote: Use of non-alphanumeric characters in tag names is \nstrongly discouraged\n and may be disallowed in future versions of Leaf.", 
            "title": "Custom tags"
        }, 
        {
            "location": "/leaf/custom-tags/#custom-tags", 
            "text": "You can extend Leaf to provide your own tags that add custom functionality. To demonstrate this, let's look at a basic example by recreating  #uppercase  together. This tag will take one argument, which is the string to uppercase.  When working with custom tags, there are four important things to know:   You should call  requireParameterCount()  with the number of parameters you expect to receive. This will throw an error if your tag is used incorrectly.  If you do or do not require a body, you should use either  requireBody()  or  requireNoBody() . Again, this will throw an error if your tag is used incorrectly.  You can read individual parameters using the  parameters  array. Each parameter will be of type  LeafData , which you can convert to concrete data types using properties such as  .string ,  .dictionary , and so on.  You must return a  Future LeafData?  containing what should be rendered. In the example below we wrap the resulting uppercase string in a  LeafData  string, then send that back wrapped in a future.   Here\u2019s example code for a  CustomUppercase  Leaf tag:  import   Async  import   Leaf  public   final   class   CustomUppercase :   Leaf . LeafTag   { \n     public   init ()   {} \n     public   func   render ( parsed :   ParsedTag ,   context :   LeafContext ,   renderer :   LeafRenderer )   throws   -   Future LeafData ?   { \n         // ensure we receive precisely one parameter \n         try   parsed . requireParameterCount ( 1 ) \n\n         // pull out our lone parameter as a string then uppercase it, or use an empty string \n         let   string   =   parsed . parameters [ 0 ]. string ?. uppercased ()   ??   \n\n         // send it back wrapped in a LeafData \n         return   Future (. string ( string )) \n     }  }   We can now register this Tag in our  configure.swift  file with:  services . register   {   container   -   LeafConfig   in \n     // take a copy of Leaf s default tags \n     var   tags   =   defaultTags \n\n     // add our custom tag \n     tags [ customuppercase ]   =   CustomUppercase () \n\n     // find the location of our Resources/Views directory \n     let   directoryConfig   =   try   container . make ( DirectoryConfig . self ,   for :   LeafRenderer . self ) \n     let   viewsDirectory   =   directoryConfig . workDir   +   Resources/Views \n\n     // put all that into a new Leaf configuration and return it \n     return   LeafConfig ( tags :   tags ,   viewsDir :   viewsDirectory )  }   Once that is complete, you can use  #customuppercase(some_variable)  to run your custom code.   Note: Use of non-alphanumeric characters in tag names is  strongly discouraged  and may be disallowed in future versions of Leaf.", 
            "title": "Custom Tags"
        }, 
        {
            "location": "/logging/getting-started/", 
            "text": "Getting Started with Logging\n\n\nThe Logging module is provided as a part of Vapor's Console package (\nvapor/console\n).  This module provides convenience APIs for creating log \n\n\n\n\nTip\n\n\nFor an in-depth look at all of Logging's APIs, check out the \nLogging API docs\n.\n\n\n\n\nUsage\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nLogging\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n \n// implies import Logging\n\n\n\n\n\n\nStandalone\n\n\nThe Logging module, part of the larger Vapor Console package, can also be used on its own with any Swift project.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n/// \ud83d\udcbb APIs for creating interactive CLI tools.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/console.git\n,\n \nfrom\n:\n \n3.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nLogging\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Logging\n to access the APIs.\n\n\nOverview\n\n\nContinue to \nLogging \u2192 Overview\n for an overview of Logging's features.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/logging/getting-started/#getting-started-with-logging", 
            "text": "The Logging module is provided as a part of Vapor's Console package ( vapor/console ).  This module provides convenience APIs for creating log    Tip  For an in-depth look at all of Logging's APIs, check out the  Logging API docs .", 
            "title": "Getting Started with Logging"
        }, 
        {
            "location": "/logging/getting-started/#usage", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  Logging  APIs when you import  Vapor .  import   Vapor   // implies import Logging", 
            "title": "Usage"
        }, 
        {
            "location": "/logging/getting-started/#standalone", 
            "text": "The Logging module, part of the larger Vapor Console package, can also be used on its own with any Swift project.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         /// \ud83d\udcbb APIs for creating interactive CLI tools. \n         . package ( url :   https://github.com/vapor/console.git ,   from :   3.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Logging ,   ...   ]) \n     ]  )   Use  import Logging  to access the APIs.", 
            "title": "Standalone"
        }, 
        {
            "location": "/logging/getting-started/#overview", 
            "text": "Continue to  Logging \u2192 Overview  for an overview of Logging's features.", 
            "title": "Overview"
        }, 
        {
            "location": "/logging/overview/", 
            "text": "Logging Overview\n\n\nThe logging package provides convenience APIs for logging information while your app is running. The \nLogger\n protocol declares a common interface for logging information. A default \nPrintLogger\n is available, but you can implement custom loggers to suit your specific needs.\n\n\nLog\n\n\nFirst, you will want to use a \nContainer\n to create an instance of \nLogger\n. Then you can use the convenience methods to log information.\n\n\nlet\n \nlogger\n \n=\n \ntry\n \nreq\n.\nmake\n(\nLogger\n.\nself\n)\n\n\nlogger\n.\ninfo\n(\nLogger created!\n)\n\n\n\n\n\n\nSee \nLogger\n in the API docs for a list of all available methods.\n\n\nCheck out \nService \n Services\n for more information on how to register a custom logger.", 
            "title": "Overview"
        }, 
        {
            "location": "/logging/overview/#logging-overview", 
            "text": "The logging package provides convenience APIs for logging information while your app is running. The  Logger  protocol declares a common interface for logging information. A default  PrintLogger  is available, but you can implement custom loggers to suit your specific needs.", 
            "title": "Logging Overview"
        }, 
        {
            "location": "/logging/overview/#log", 
            "text": "First, you will want to use a  Container  to create an instance of  Logger . Then you can use the convenience methods to log information.  let   logger   =   try   req . make ( Logger . self )  logger . info ( Logger created! )   See  Logger  in the API docs for a list of all available methods.  Check out  Service   Services  for more information on how to register a custom logger.", 
            "title": "Log"
        }, 
        {
            "location": "/multipart/getting-started/", 
            "text": "Getting Started with Multipart\n\n\nMultipart (\nvapor/multipart\n) is a small package that helps you parse and serialize \nmultipart\n encoded data. Multipart is a widely-supported encoding on the web. It's most often used for serializing web forms, especially ones that contain rich media like images.\n\n\nThe Multipart package makes it easy to use this encoding by integrating directly with \nCodable\n.\n\n\nVapor\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nMultipart\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n\n\n\n\n\n\nStandalone\n\n\nThe Multipart package is lightweight, pure-Swift, and has very few dependencies. This means it can be used to work with multipart-encoded data for any Swift project\neven one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/multipart.git\n,\n \nfrom\n:\n \n3.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nMultipart\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Multipart\n to access the APIs.\n\n\n\n\nWarning\n\n\nSome of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Multipart package in general.\nVisit the \nAPI Docs\n for Multipart-specific API info.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/multipart/getting-started/#getting-started-with-multipart", 
            "text": "Multipart ( vapor/multipart ) is a small package that helps you parse and serialize  multipart  encoded data. Multipart is a widely-supported encoding on the web. It's most often used for serializing web forms, especially ones that contain rich media like images.  The Multipart package makes it easy to use this encoding by integrating directly with  Codable .", 
            "title": "Getting Started with Multipart"
        }, 
        {
            "location": "/multipart/getting-started/#vapor", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  Multipart  APIs when you import  Vapor .  import   Vapor", 
            "title": "Vapor"
        }, 
        {
            "location": "/multipart/getting-started/#standalone", 
            "text": "The Multipart package is lightweight, pure-Swift, and has very few dependencies. This means it can be used to work with multipart-encoded data for any Swift project even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/multipart.git ,   from :   3.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Multipart ,   ...   ]) \n     ]  )   Use  import Multipart  to access the APIs.   Warning  Some of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Multipart package in general.\nVisit the  API Docs  for Multipart-specific API info.", 
            "title": "Standalone"
        }, 
        {
            "location": "/multipart/overview/", 
            "text": "Using Multipart\n\n\nMultipart is a widely-supported encoding on the web. It's most often used for serializing web forms, especially ones that contain rich media like images. It allows for arbitrary data to be encoded in each part thanks to a unique delimiter \nboundary\n that is defined separately. This boundary is guaranteed by the client to not appear anywhere in the data.\n\n\nMultipart is a powerful encoding, however it is rarely used in its base format. Most commonly, \nmultipart/form-data\n is used. This encoding adds a \n\"name\"\n property to each part of the multipart data. This is required for serializing web forms. For the rest of this guide, assume we are talking about \nmultipart/form-data\n unless otherwise specified.\n\n\n\n\nTip\n\n\nMultipart integrates with \nContent\n like all other encoding methods in Vapor. See \nVapor \n Content\n for more information about the \nContent\n protocol. \n\n\n\n\nLet's take a look at how to decode a \nmultipart/form-data\n-encoded request.\n\n\nDecode\n\n\nMost often, you will be decoding \nmultipart/form-data\n-encoded requests from a web form. Let's take a look at what one of these requests might look like. After that, we will take a look at what the HTML form for that request would look like.\n\n\nRequest\n\n\nHere is an example \nmultipart/form-data\n-encoded request for creating a new user.\n\n\nPOST\n \n/users\n \nHTTP\n/\n1.1\n\n\nContent-Type\n:\n \nmultipart/form-data; boundary=123\n\n\n--123\nContent-Disposition: form-data; name=\nname\n\n\nVapor\n--123\nContent-Disposition: form-data; name=\nage\n\n\n3\n--123\nContent-Disposition: form-data; name=\nimage\n; filename=\ndroplet.png\n\n\n\ncontents of image\n\n--123--\n\n\n\n\n\nYou can see the multipart data uses a \nboundary\n (in this case it is \n\"123\"\n) to separate the data. This will usually be a longer string. The client sending a multipart-encoded request must ensure that the boundary it supplies does not appear anywhere in the content it is sending you. That's what allows this encoding to be used to send things like files.\n\n\nForm\n\n\nThere are many ways to create a multipart-encoded request, but the most common is an HTML web form. Here is what the HTML form for this request might have looked like.\n\n\nform\n \nmethod\n=\nPOST\n \naction\n=\n/users\n \nenctype\n=\nmultipart/form-data\n\n    \ninput\n \ntype\n=\ntext\n \nname\n=\nname\n\n    \ninput\n \ntype\n=\ntext\n \nname\n=\nage\n\n    \ninput\n \ntype\n=\nfile\n \nname\n=\nimage\n\n\n/\nform\n\n\n\n\n\n\nTake note of the \nenctype\n attribute on the \nform\n as well as the \nfile\n type input. This is what allows us to send files via the web form.\n\n\nContent\n\n\nNow let's take a look at how we would handle this request in Vapor. The first step (as always with \nContent\n) is to create a \nCodable\n struct that represents the data structure.\n\n\nimport\n \nVapor\n\n\n\nstruct\n \nUser\n:\n \nContent\n \n{\n\n    \nvar\n \nname\n:\n \nString\n\n    \nvar\n \nage\n:\n \nInt\n\n    \nvar\n \nimage\n:\n \nData\n\n\n}\n\n\n\n\n\n\n\n\nTip\n\n\nYou can use \nFile\n instead of \nData\n if you would also like to access the filename.\n\n\n\n\nNow that we have our \nUser\n struct, let's decode that request! We can use the \nContentContainer\n to do this easily.\n\n\nrouter\n.\npost\n(\nusers\n)\n \n{\n \nreq\n \n-\n \nFuture\nHTTPStatus\n \nin\n\n    \nreturn\n \ntry\n \nreq\n.\ncontent\n.\ndecode\n(\nUser\n.\nself\n).\nmap\n(\nto\n:\n \nHTTPStatus\n.\nself\n)\n \n{\n \nuser\n \nin\n\n        \nprint\n(\nuser\n.\nname\n)\n \n// \nVapor\n\n        \nprint\n(\nuser\n.\nage\n)\n \n// 3\n\n        \nprint\n(\nuser\n.\nimage\n)\n \n// Raw image data\n\n        \nreturn\n \n.\nok\n\n    \n}\n\n\n}\n\n\n\n\n\n\nNow when you post the form to \n/users\n, you should see the information printed in the console. Nice work!\n\n\nEncode\n\n\nAPIs encode multipart data much less often than they decode it. However, encoding is just as easy with Vapor. Using our same \nUser\n struct from the previous example, here is how we can encode a multipart-encoded response.\n\n\nrouter\n.\nget\n(\nmultipart\n)\n \n{\n \nreq\n \n-\n \nUser\n \nin\n\n    \nlet\n \nres\n \n=\n \nreq\n.\nmakeResponse\n()\n\n    \nlet\n \nuser\n \n=\n \nUser\n(\nname\n:\n \nVapor\n,\n \nage\n:\n \n3\n,\n \nimage\n:\n \nData\n(...))\n\n    \nres\n.\ncontent\n.\nencode\n(\nuser\n,\n \nas\n:\n \n.\nformData\n)\n\n    \nreturn\n \nuser\n\n\n}\n\n\n\n\n\n\n\n\nTip\n\n\nIf you set a default \nMediaType\n on your \nContent\n types, then you can return them directly in the route closure.\n\n\n\n\nParsing \n Serializing\n\n\nThe Multipart package also offers APIs for parsing and serializing \nmultipart/form-data\n data without using \nCodable\n. Check out the \nAPI Docs\n for more information on using those APIs.", 
            "title": "Overview"
        }, 
        {
            "location": "/multipart/overview/#using-multipart", 
            "text": "Multipart is a widely-supported encoding on the web. It's most often used for serializing web forms, especially ones that contain rich media like images. It allows for arbitrary data to be encoded in each part thanks to a unique delimiter  boundary  that is defined separately. This boundary is guaranteed by the client to not appear anywhere in the data.  Multipart is a powerful encoding, however it is rarely used in its base format. Most commonly,  multipart/form-data  is used. This encoding adds a  \"name\"  property to each part of the multipart data. This is required for serializing web forms. For the rest of this guide, assume we are talking about  multipart/form-data  unless otherwise specified.   Tip  Multipart integrates with  Content  like all other encoding methods in Vapor. See  Vapor   Content  for more information about the  Content  protocol.    Let's take a look at how to decode a  multipart/form-data -encoded request.", 
            "title": "Using Multipart"
        }, 
        {
            "location": "/multipart/overview/#decode", 
            "text": "Most often, you will be decoding  multipart/form-data -encoded requests from a web form. Let's take a look at what one of these requests might look like. After that, we will take a look at what the HTML form for that request would look like.", 
            "title": "Decode"
        }, 
        {
            "location": "/multipart/overview/#request", 
            "text": "Here is an example  multipart/form-data -encoded request for creating a new user.  POST   /users   HTTP / 1.1  Content-Type :   multipart/form-data; boundary=123 \n\n--123\nContent-Disposition: form-data; name= name \n\nVapor\n--123\nContent-Disposition: form-data; name= age \n\n3\n--123\nContent-Disposition: form-data; name= image ; filename= droplet.png  contents of image \n--123--  You can see the multipart data uses a  boundary  (in this case it is  \"123\" ) to separate the data. This will usually be a longer string. The client sending a multipart-encoded request must ensure that the boundary it supplies does not appear anywhere in the content it is sending you. That's what allows this encoding to be used to send things like files.", 
            "title": "Request"
        }, 
        {
            "location": "/multipart/overview/#form", 
            "text": "There are many ways to create a multipart-encoded request, but the most common is an HTML web form. Here is what the HTML form for this request might have looked like.  form   method = POST   action = /users   enctype = multipart/form-data \n     input   type = text   name = name \n     input   type = text   name = age \n     input   type = file   name = image  / form   Take note of the  enctype  attribute on the  form  as well as the  file  type input. This is what allows us to send files via the web form.", 
            "title": "Form"
        }, 
        {
            "location": "/multipart/overview/#content", 
            "text": "Now let's take a look at how we would handle this request in Vapor. The first step (as always with  Content ) is to create a  Codable  struct that represents the data structure.  import   Vapor  struct   User :   Content   { \n     var   name :   String \n     var   age :   Int \n     var   image :   Data  }    Tip  You can use  File  instead of  Data  if you would also like to access the filename.   Now that we have our  User  struct, let's decode that request! We can use the  ContentContainer  to do this easily.  router . post ( users )   {   req   -   Future HTTPStatus   in \n     return   try   req . content . decode ( User . self ). map ( to :   HTTPStatus . self )   {   user   in \n         print ( user . name )   //  Vapor \n         print ( user . age )   // 3 \n         print ( user . image )   // Raw image data \n         return   . ok \n     }  }   Now when you post the form to  /users , you should see the information printed in the console. Nice work!", 
            "title": "Content"
        }, 
        {
            "location": "/multipart/overview/#encode", 
            "text": "APIs encode multipart data much less often than they decode it. However, encoding is just as easy with Vapor. Using our same  User  struct from the previous example, here is how we can encode a multipart-encoded response.  router . get ( multipart )   {   req   -   User   in \n     let   res   =   req . makeResponse () \n     let   user   =   User ( name :   Vapor ,   age :   3 ,   image :   Data (...)) \n     res . content . encode ( user ,   as :   . formData ) \n     return   user  }    Tip  If you set a default  MediaType  on your  Content  types, then you can return them directly in the route closure.", 
            "title": "Encode"
        }, 
        {
            "location": "/multipart/overview/#parsing-serializing", 
            "text": "The Multipart package also offers APIs for parsing and serializing  multipart/form-data  data without using  Codable . Check out the  API Docs  for more information on using those APIs.", 
            "title": "Parsing &amp; Serializing"
        }, 
        {
            "location": "/mysql/getting-started/", 
            "text": "Warning\n\n\nMySQL 3.0 is still in beta. Some documentation may be missing or out of date.\n\n\n\n\nGetting Started with MySQL\n\n\nMySQL\n is a widely-used, open-source database. It has an extremely popular wire-protocol that other open-source databases like \nMariaDB\n also support.\n\n\nYou can use MySQL with Vapor (or any server-side Swift framework) by either:\n\n\n\n\nUsing \nFluent MySQL\n ORM.\n\n\nUse just \nMySQL core\n.\n\n\n\n\nWe recommend using the ORM since it does a lot of the hard work for you. Check out the respective guides to learn more.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/mysql/getting-started/#getting-started-with-mysql", 
            "text": "MySQL  is a widely-used, open-source database. It has an extremely popular wire-protocol that other open-source databases like  MariaDB  also support.  You can use MySQL with Vapor (or any server-side Swift framework) by either:   Using  Fluent MySQL  ORM.  Use just  MySQL core .   We recommend using the ORM since it does a lot of the hard work for you. Check out the respective guides to learn more.", 
            "title": "Getting Started with MySQL"
        }, 
        {
            "location": "/mysql/fluent/", 
            "text": "Fluent MySQL\n\n\nFluent MySQL (\nvapor/fluent-mysql\n) is a type-safe, fast, and easy-to-use ORM for MySQL built on top of \nFluent\n.\n\n\n\n\nSeealso\n\n\nThe Fluent MySQL package is built on top of \nFluent\n and the pure Swift, NIO-based \nMySQL core\n. You should refer to their guides for more information about subjects not covered here.\n\n\n\n\nGetting Started\n\n\nThis section will show you how to add Fluent MySQL to your project and create your first \nMySQLModel\n.\n\n\nPackage\n\n\nThe first step to using Fluent MySQL is adding it as a dependency to your project in your SPM package manifest file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nMyApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n/// Any other dependencies ...\n\n\n        \n// \ud83d\udd8b\ud83d\udc2c Swift ORM (queries, models, relations, etc) built on MySQL.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/fluent-mysql.git\n,\n \nfrom\n:\n \n3.0.0-rc\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nFluentMySQL\n,\n \n...]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nDon't forget to add the module as a dependency in the \ntargets\n array. Once you have added the dependency, regenerate your Xcode project with the following command:\n\n\nvapor xcode\n\n\n\n\n\nModel\n\n\nNow let's create our first \nMySQLModel\n. Models represent tables in your MySQL database and they are the primary method of interacting with your data. \n\n\n/// A simple user.\n\n\nfinal\n \nclass\n \nUser\n:\n \nMySQLModel\n \n{\n\n    \n/// The unique identifier for this user.\n\n    \nvar\n \nid\n:\n \nInt\n?\n\n\n    \n/// The user\ns full name.\n\n    \nvar\n \nname\n:\n \nString\n\n\n    \n/// The user\ns current age in years.\n\n    \nvar\n \nage\n:\n \nInt\n\n\n    \n/// Creates a new user.\n\n    \ninit\n(\nid\n:\n \nInt\n?\n \n=\n \nnil\n,\n \nname\n:\n \nString\n,\n \nage\n:\n \nInt\n)\n \n{\n\n        \nself\n.\nid\n \n=\n \nid\n\n        \nself\n.\nname\n \n=\n \nname\n\n        \nself\n.\nage\n \n=\n \nage\n\n    \n}\n\n\n}\n\n\n\n\n\n\nThe example above shows a \nMySQLModel\n for a simple model representing a user. You can make both \nstruct\ns and \nclass\nes a model. You can even conform types that come from external modules. The only requirement is that these types conform to \nCodable\n, which must be declared on the base type for synthesized (automatic) conformance.\n\n\nStandard practice with MySQL databases is using an auto-generated \nINTEGER\n for creating and storing unique identifiers in the \nid\n column. It's also possible to use \nUUID\ns or even \nString\ns for your identifiers. There are convenience protocol for that. \n\n\n\n\n\n\n\n\nprotocol\n\n\ntype\n\n\nkey\n\n\n\n\n\n\n\n\n\n\nMySQLModel\n\n\nInt\n\n\nid\n\n\n\n\n\n\nMySQLUUIDModel\n\n\nUUID\n\n\nid\n\n\n\n\n\n\nMySQLStringModel\n\n\nString\n\n\nid\n\n\n\n\n\n\n\n\n\n\nSeealso\n\n\nTake a look at \nFluent \n Model\n for more information on creating models with custom ID types and keys.\n\n\n\n\nMigration\n\n\nAll of your models (with some rare exceptions) should have a corresponding table\nor \nschema\nin your database. You can use a \nFluent \n Migration\n to automatically generate this schema in a testable, maintainable way. Fluent makes it easy to automatically generate a migration for your model\n\n\n\n\nTip\n\n\nIf you are creating models to represent an existing table or database, you can skip this step.\n\n\n\n\n/// Allows `User` to be used as a migration.\n\n\nextension\n \nUser\n:\n \nMigration\n \n{\n \n}\n\n\n\n\n\n\nThat's all it takes. Fluent uses Codable to analyze your model and will attempt to create the best possible schema for it.\n\n\nTake a look at \nFluent \n Migration\n if you are interested in customizing this migration.\n\n\nConfigure\n\n\nThe final step is to configure your database. At a minimum, this requires adding two things to your \nconfigure.swift\n file.\n\n\n\n\nFluentMySQLProvider\n\n\nMigrationConfig\n\n\n\n\nLet's take a look.\n\n\nimport\n \nFluentMySQL\n\n\n\n/// ...\n\n\n\n/// Register providers first\n\n\ntry\n \nservices\n.\nregister\n(\nFluentMySQLProvider\n())\n\n\n\n/// Configure migrations\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmodel\n:\n \nUser\n.\nself\n,\n \ndatabase\n:\n \n.\nmysql\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n/// Other services....\n\n\n\n\n\n\nRegistering the provider will add all of the services required for Fluent MySQL to work properly. It also includes a default database config struct that uses typical development environment credentials. \n\n\nYou can of course override this config struct if you have non-standard credentials.\n\n\n/// Register custom MySQL Config\n\n\nlet\n \nmysqlConfig\n \n=\n \nMySQLDatabaseConfig\n(\nhostname\n:\n \nlocalhost\n,\n \nport\n:\n \n3306\n,\n \nusername\n:\n \nvapor\n)\n\n\nservices\n.\nregister\n(\nmysqlConfig\n)\n\n\n\n\n\n\nOnce you have the \nMigrationConfig\n added, you should be able to run your application and see the following:\n\n\nMigrating mysql DB\nMigrations \ncomplete\n\nServer starting on http://localhost:8080\n\n\n\n\n\nQuery\n\n\nNow that you have created a model and a corresponding schema in your database, let's make your first query.\n\n\nrouter\n.\nget\n(\nusers\n)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nUser\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n}\n\n\n\n\n\n\nIf you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent MySQL model and migration working.\n\n\nConnection\n\n\nWith Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a \"raw query\".\n\n\nLet's take a look at a raw MySQL query.\n\n\nrouter\n.\nget\n(\nmysql-version\n)\n \n{\n \nreq\n \n-\n \nFuture\nString\n \nin\n\n    \nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nmysql\n)\n \n{\n \nconn\n \nin\n\n        \nreturn\n \ntry\n \nconn\n.\nquery\n(\nselect @@version as v;\n).\nmap\n(\nto\n:\n \nString\n.\nself\n)\n \n{\n \nrows\n \nin\n\n            \nreturn\n \ntry\n \nrows\n[\n0\n].\nfirstValue\n(\nforColumn\n:\n \nv\n)?.\ndecode\n(\nString\n.\nself\n)\n \n??\n \nn/a\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nIn the above example, \nwithPooledConnection(to:)\n is used to create a connection to the database identified by \n.mysql\n. This is the default database identifier. See \nFluent \n Database\n to learn more.\n\n\nOnce we have the \nMySQLConnection\n, we can perform a query on it. You can learn more about the methods available in \nMySQL \n Core\n.", 
            "title": "Fluent MySQL"
        }, 
        {
            "location": "/mysql/fluent/#fluent-mysql", 
            "text": "Fluent MySQL ( vapor/fluent-mysql ) is a type-safe, fast, and easy-to-use ORM for MySQL built on top of  Fluent .   Seealso  The Fluent MySQL package is built on top of  Fluent  and the pure Swift, NIO-based  MySQL core . You should refer to their guides for more information about subjects not covered here.", 
            "title": "Fluent MySQL"
        }, 
        {
            "location": "/mysql/fluent/#getting-started", 
            "text": "This section will show you how to add Fluent MySQL to your project and create your first  MySQLModel .", 
            "title": "Getting Started"
        }, 
        {
            "location": "/mysql/fluent/#package", 
            "text": "The first step to using Fluent MySQL is adding it as a dependency to your project in your SPM package manifest file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   MyApp , \n     dependencies :   [ \n         /// Any other dependencies ... \n\n         // \ud83d\udd8b\ud83d\udc2c Swift ORM (queries, models, relations, etc) built on MySQL. \n         . package ( url :   https://github.com/vapor/fluent-mysql.git ,   from :   3.0.0-rc ), \n     ], \n     targets :   [ \n         . target ( name :   App ,   dependencies :   [ FluentMySQL ,   ...]), \n         . target ( name :   Run ,   dependencies :   [ App ]), \n         . testTarget ( name :   AppTests ,   dependencies :   [ App ]), \n     ]  )   Don't forget to add the module as a dependency in the  targets  array. Once you have added the dependency, regenerate your Xcode project with the following command:  vapor xcode", 
            "title": "Package"
        }, 
        {
            "location": "/mysql/fluent/#model", 
            "text": "Now let's create our first  MySQLModel . Models represent tables in your MySQL database and they are the primary method of interacting with your data.   /// A simple user.  final   class   User :   MySQLModel   { \n     /// The unique identifier for this user. \n     var   id :   Int ? \n\n     /// The user s full name. \n     var   name :   String \n\n     /// The user s current age in years. \n     var   age :   Int \n\n     /// Creates a new user. \n     init ( id :   Int ?   =   nil ,   name :   String ,   age :   Int )   { \n         self . id   =   id \n         self . name   =   name \n         self . age   =   age \n     }  }   The example above shows a  MySQLModel  for a simple model representing a user. You can make both  struct s and  class es a model. You can even conform types that come from external modules. The only requirement is that these types conform to  Codable , which must be declared on the base type for synthesized (automatic) conformance.  Standard practice with MySQL databases is using an auto-generated  INTEGER  for creating and storing unique identifiers in the  id  column. It's also possible to use  UUID s or even  String s for your identifiers. There are convenience protocol for that.      protocol  type  key      MySQLModel  Int  id    MySQLUUIDModel  UUID  id    MySQLStringModel  String  id      Seealso  Take a look at  Fluent   Model  for more information on creating models with custom ID types and keys.", 
            "title": "Model"
        }, 
        {
            "location": "/mysql/fluent/#migration", 
            "text": "All of your models (with some rare exceptions) should have a corresponding table or  schema in your database. You can use a  Fluent   Migration  to automatically generate this schema in a testable, maintainable way. Fluent makes it easy to automatically generate a migration for your model   Tip  If you are creating models to represent an existing table or database, you can skip this step.   /// Allows `User` to be used as a migration.  extension   User :   Migration   {   }   That's all it takes. Fluent uses Codable to analyze your model and will attempt to create the best possible schema for it.  Take a look at  Fluent   Migration  if you are interested in customizing this migration.", 
            "title": "Migration"
        }, 
        {
            "location": "/mysql/fluent/#configure", 
            "text": "The final step is to configure your database. At a minimum, this requires adding two things to your  configure.swift  file.   FluentMySQLProvider  MigrationConfig   Let's take a look.  import   FluentMySQL  /// ...  /// Register providers first  try   services . register ( FluentMySQLProvider ())  /// Configure migrations  var   migrations   =   MigrationConfig ()  migrations . add ( model :   User . self ,   database :   . mysql )  services . register ( migrations )  /// Other services....   Registering the provider will add all of the services required for Fluent MySQL to work properly. It also includes a default database config struct that uses typical development environment credentials.   You can of course override this config struct if you have non-standard credentials.  /// Register custom MySQL Config  let   mysqlConfig   =   MySQLDatabaseConfig ( hostname :   localhost ,   port :   3306 ,   username :   vapor )  services . register ( mysqlConfig )   Once you have the  MigrationConfig  added, you should be able to run your application and see the following:  Migrating mysql DB\nMigrations  complete \nServer starting on http://localhost:8080", 
            "title": "Configure"
        }, 
        {
            "location": "/mysql/fluent/#query", 
            "text": "Now that you have created a model and a corresponding schema in your database, let's make your first query.  router . get ( users )   {   req   in \n     return   User . query ( on :   req ). all ()  }   If you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent MySQL model and migration working.", 
            "title": "Query"
        }, 
        {
            "location": "/mysql/fluent/#connection", 
            "text": "With Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a \"raw query\".  Let's take a look at a raw MySQL query.  router . get ( mysql-version )   {   req   -   Future String   in \n     return   req . withPooledConnection ( to :   . mysql )   {   conn   in \n         return   try   conn . query ( select @@version as v; ). map ( to :   String . self )   {   rows   in \n             return   try   rows [ 0 ]. firstValue ( forColumn :   v )?. decode ( String . self )   ??   n/a \n         } \n     }  }   In the above example,  withPooledConnection(to:)  is used to create a connection to the database identified by  .mysql . This is the default database identifier. See  Fluent   Database  to learn more.  Once we have the  MySQLConnection , we can perform a query on it. You can learn more about the methods available in  MySQL   Core .", 
            "title": "Connection"
        }, 
        {
            "location": "/mysql/core/", 
            "text": "MySQL Core\n\n\nMySQL (\nvapor/mysql\n) is a pure-Swift (no \nlibmysql\n dependency), event-driven, non-blocking driver for MySQL. It's built on top of the \nSwiftNIO\n networking library.\n\n\n\n\nSeealso\n\n\nThe higher-level, Fluent MySQL ORM guide is located at \nMySQL \n Fluent\n\n\n\n\nUsing just the MySQL package for your project may be a good idea if any of the following are true.\n\n\n\n\nYou have an existing DB with non-standard structure.\n\n\nYou rely heavily on custom or complex SQL queries.\n\n\nYou just plain don't like ORMs.\n\n\n\n\nMySQL core is built on top of DatabaseKit which provides some conveniences like connection pooling and integrations with Vapor's \nServices\n architecture.\n\n\n\n\nTip\n\n\nEven if you do choose to use \nFluent MySQL\n, all of the features of MySQL core will be available to you.\n\n\n\n\nGetting Started\n\n\nLet's take a look at how you can get started using MySQL core.\n\n\nPackage\n\n\nThe first step to using MySQL core is adding it as a dependency to your project in your SPM package manifest file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nMyApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n/// Any other dependencies ...\n\n\n        \n// \ud83d\udc2c Non-blocking, event-driven Swift client for MySQL.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/mysql.git\n,\n \nfrom\n:\n \n3.0.0-rc\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nMySQL\n,\n \n...]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nDon't forget to add the module as a dependency in the \ntargets\n array. Once you have added the dependency, regenerate your Xcode project with the following command:\n\n\nvapor xcode\n\n\n\n\n\nConfig\n\n\nThe next step is to configure the database in your \nconfigure.swift\n file.\n\n\nimport\n \nMySQL\n\n\n\n/// ...\n\n\n\n/// Register providers first\n\n\ntry\n \nservices\n.\nregister\n(\nMySQLProvider\n())\n\n\n\n\n\n\nRegistering the provider will add all of the services required for MySQL to work properly. It also includes a default database config struct that uses typical development environment credentials.\n\n\nYou can of course override this config struct if you have non-standard credentials.\n\n\n/// Register custom MySQL Config\n\n\nlet\n \nmysqlConfig\n \n=\n \nMySQLDatabaseConfig\n(\nhostname\n:\n \nlocalhost\n,\n \nport\n:\n \n3306\n,\n \nusername\n:\n \nvapor\n)\n\n\nservices\n.\nregister\n(\nmysqlConfig\n)\n\n\n\n\n\n\nQuery\n\n\nNow that the database is configured, you can make your first query.\n\n\nrouter\n.\nget\n(\nmysql-version\n)\n \n{\n \nreq\n \n-\n \nFuture\nString\n \nin\n\n    \nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nmysql\n)\n \n{\n \nconn\n \nin\n\n        \nreturn\n \ntry\n \nconn\n.\nquery\n(\nselect @@version as v;\n).\nmap\n(\nto\n:\n \nString\n.\nself\n)\n \n{\n \nrows\n \nin\n\n            \nreturn\n \ntry\n \nrows\n[\n0\n].\nfirstValue\n(\nforColumn\n:\n \nv\n)?.\ndecode\n(\nString\n.\nself\n)\n \n??\n \nn/a\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nVisiting this route should display your MySQL version.\n\n\nConnection\n\n\nA \nMySQLConnection\n is normally created using the \nRequest\n container and can perform two different types of queries.\n\n\nCreate\n\n\nThere are a few methods for creating a \nMySQLConnection\n with a \nContainer\n (typically a \nRequest\n).\n\n\nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nmysql\n)\n \n{\n \nconn\n \nin\n\n    \n/// ...\n\n\n}\n\n\nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nmysql\n)\n \n{\n \nconn\n \nin\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nAs the names imply,  \nwithPooledConnection(to:)\n utilizes a connection pool. \nwithConnection(to:)\n does not. Connection pooling is a great way to ensure your application does not exceed the limits of your database, even under peak load.\n\n\nYou can also create a connection manually using \nMySQLDatabase.makeConnection(on:)\n and passing a \nWorker\n.\n\n\nSimply Query\n\n\nUse \n.simpleQuery(_:)\n to perform a query on your MySQL database that does not bind any parameters. Some queries you send to MySQL may actually require that you use the \nsimpleQuery(_:)\n method instead of the parameterized method.\n\n\n\n\nNote\n\n\nThis method sends and receives data as text-encoded, meaning it is not optimal for transmitting things like integers.\n\n\n\n\nlet\n \nrows\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nmysql\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nsimpleQuery\n(\nSELECT * FROM users;\n)\n\n\n}\n\n\nprint\n(\nrows\n)\n \n// Future\n[[MySQLColumn: MySQLData]]\n\n\n\n\n\n\nYou can also choose to receive each row in a callback, which is great for conserving memory for large queries.\n\n\nlet\n \ndone\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nmysql\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nsimpleQuery\n(\nSELECT * FROM users;\n)\n \n{\n \nrow\n \nin\n\n        \nprint\n(\nrow\n)\n \n// [MySQLColumn: MySQLData]\n\n    \n}\n\n\n}\n\n\nprint\n(\ndone\n)\n \n// Future\nVoid\n\n\n\n\n\n\nParameterized Query\n\n\nMySQL also supports sending parameterized queries (sometimes called prepared statements). This method allows you to insert data placeholders into the SQL string and send the values separately.\n\n\nData sent via parameterized queries is binary encoded, making it more efficient for sending some data types. In general, you should use parameterized queries where ever possible.\n\n\nlet\n \nusers\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nmysql\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \ntry\n \nconn\n.\nquery\n(\nSELECT *  users WHERE name = $1;\n,\n \n[\nVapor\n])\n\n\n}\n\n\nprint\n(\nusers\n)\n \n// Future\n[[MySQLColumn: MySQLData]]\n\n\n\n\n\n\nYou can also provide a callback, similar to simple queries, for handling each row individually.", 
            "title": "MySQL Core"
        }, 
        {
            "location": "/mysql/core/#mysql-core", 
            "text": "MySQL ( vapor/mysql ) is a pure-Swift (no  libmysql  dependency), event-driven, non-blocking driver for MySQL. It's built on top of the  SwiftNIO  networking library.   Seealso  The higher-level, Fluent MySQL ORM guide is located at  MySQL   Fluent   Using just the MySQL package for your project may be a good idea if any of the following are true.   You have an existing DB with non-standard structure.  You rely heavily on custom or complex SQL queries.  You just plain don't like ORMs.   MySQL core is built on top of DatabaseKit which provides some conveniences like connection pooling and integrations with Vapor's  Services  architecture.   Tip  Even if you do choose to use  Fluent MySQL , all of the features of MySQL core will be available to you.", 
            "title": "MySQL Core"
        }, 
        {
            "location": "/mysql/core/#getting-started", 
            "text": "Let's take a look at how you can get started using MySQL core.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/mysql/core/#package", 
            "text": "The first step to using MySQL core is adding it as a dependency to your project in your SPM package manifest file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   MyApp , \n     dependencies :   [ \n         /// Any other dependencies ... \n\n         // \ud83d\udc2c Non-blocking, event-driven Swift client for MySQL. \n         . package ( url :   https://github.com/vapor/mysql.git ,   from :   3.0.0-rc ), \n     ], \n     targets :   [ \n         . target ( name :   App ,   dependencies :   [ MySQL ,   ...]), \n         . target ( name :   Run ,   dependencies :   [ App ]), \n         . testTarget ( name :   AppTests ,   dependencies :   [ App ]), \n     ]  )   Don't forget to add the module as a dependency in the  targets  array. Once you have added the dependency, regenerate your Xcode project with the following command:  vapor xcode", 
            "title": "Package"
        }, 
        {
            "location": "/mysql/core/#config", 
            "text": "The next step is to configure the database in your  configure.swift  file.  import   MySQL  /// ...  /// Register providers first  try   services . register ( MySQLProvider ())   Registering the provider will add all of the services required for MySQL to work properly. It also includes a default database config struct that uses typical development environment credentials.  You can of course override this config struct if you have non-standard credentials.  /// Register custom MySQL Config  let   mysqlConfig   =   MySQLDatabaseConfig ( hostname :   localhost ,   port :   3306 ,   username :   vapor )  services . register ( mysqlConfig )", 
            "title": "Config"
        }, 
        {
            "location": "/mysql/core/#query", 
            "text": "Now that the database is configured, you can make your first query.  router . get ( mysql-version )   {   req   -   Future String   in \n     return   req . withPooledConnection ( to :   . mysql )   {   conn   in \n         return   try   conn . query ( select @@version as v; ). map ( to :   String . self )   {   rows   in \n             return   try   rows [ 0 ]. firstValue ( forColumn :   v )?. decode ( String . self )   ??   n/a \n         } \n     }  }   Visiting this route should display your MySQL version.", 
            "title": "Query"
        }, 
        {
            "location": "/mysql/core/#connection", 
            "text": "A  MySQLConnection  is normally created using the  Request  container and can perform two different types of queries.", 
            "title": "Connection"
        }, 
        {
            "location": "/mysql/core/#create", 
            "text": "There are a few methods for creating a  MySQLConnection  with a  Container  (typically a  Request ).  return   req . withPooledConnection ( to :   . mysql )   {   conn   in \n     /// ...  }  return   req . withConnection ( to :   . mysql )   {   conn   in \n     /// ...  }   As the names imply,   withPooledConnection(to:)  utilizes a connection pool.  withConnection(to:)  does not. Connection pooling is a great way to ensure your application does not exceed the limits of your database, even under peak load.  You can also create a connection manually using  MySQLDatabase.makeConnection(on:)  and passing a  Worker .", 
            "title": "Create"
        }, 
        {
            "location": "/mysql/core/#simply-query", 
            "text": "Use  .simpleQuery(_:)  to perform a query on your MySQL database that does not bind any parameters. Some queries you send to MySQL may actually require that you use the  simpleQuery(_:)  method instead of the parameterized method.   Note  This method sends and receives data as text-encoded, meaning it is not optimal for transmitting things like integers.   let   rows   =   req . withPooledConnection ( to :   . mysql )   {   conn   in \n     return   conn . simpleQuery ( SELECT * FROM users; )  }  print ( rows )   // Future [[MySQLColumn: MySQLData]]   You can also choose to receive each row in a callback, which is great for conserving memory for large queries.  let   done   =   req . withPooledConnection ( to :   . mysql )   {   conn   in \n     return   conn . simpleQuery ( SELECT * FROM users; )   {   row   in \n         print ( row )   // [MySQLColumn: MySQLData] \n     }  }  print ( done )   // Future Void", 
            "title": "Simply Query"
        }, 
        {
            "location": "/mysql/core/#parameterized-query", 
            "text": "MySQL also supports sending parameterized queries (sometimes called prepared statements). This method allows you to insert data placeholders into the SQL string and send the values separately.  Data sent via parameterized queries is binary encoded, making it more efficient for sending some data types. In general, you should use parameterized queries where ever possible.  let   users   =   req . withPooledConnection ( to :   . mysql )   {   conn   in \n     return   try   conn . query ( SELECT *  users WHERE name = $1; ,   [ Vapor ])  }  print ( users )   // Future [[MySQLColumn: MySQLData]]   You can also provide a callback, similar to simple queries, for handling each row individually.", 
            "title": "Parameterized Query"
        }, 
        {
            "location": "/postgresql/getting-started/", 
            "text": "Warning\n\n\nPostgreSQL 1.0 is still in beta. Some documentation may be missing or out of date.\n\n\n\n\nGetting Started with PostgreSQL\n\n\nPostgreSQL\n is a powerful, open-source database that puts an emphasis on standards compliance. PostgreSQL's strong type-system make it a great fit with Swift, and it is the preferred database for use with Vapor.\n\n\nYou can use PostgreSQL with Vapor (or any server-side Swift framework) by either:\n\n\n\n\nUsing \nFluent PostgreSQL\n ORM.\n\n\nUse just \nPostgreSQL core\n.\n\n\n\n\nWe recommend using the ORM since it does a lot of the hard work for you. Check out the respective guides to learn more.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/postgresql/getting-started/#getting-started-with-postgresql", 
            "text": "PostgreSQL  is a powerful, open-source database that puts an emphasis on standards compliance. PostgreSQL's strong type-system make it a great fit with Swift, and it is the preferred database for use with Vapor.  You can use PostgreSQL with Vapor (or any server-side Swift framework) by either:   Using  Fluent PostgreSQL  ORM.  Use just  PostgreSQL core .   We recommend using the ORM since it does a lot of the hard work for you. Check out the respective guides to learn more.", 
            "title": "Getting Started with PostgreSQL"
        }, 
        {
            "location": "/postgresql/fluent/", 
            "text": "Fluent PostgreSQL\n\n\nFluent PostgreSQL (\nvapor/fluent-postgresql\n) is a type-safe, fast, and easy-to-use ORM for PostgreSQL built on top of \nFluent\n.\n\n\n\n\nSeealso\n\n\nThe Fluent PostgreSQL package is built on top of \nFluent\n and the pure Swift, NIO-based \nPostgreSQL core\n. You should refer to their guides for more information about subjects not covered here.\n\n\n\n\nGetting Started\n\n\nThis section will show you how to add Fluent PostgreSQL to your project and create your first \nPostgreSQLModel\n.\n\n\nPackage\n\n\nThe first step to using Fluent PostgreSQL is adding it as a dependency to your project in your SPM package manifest file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nMyApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n/// Any other dependencies ...\n\n\n        \n// \ud83d\udd8b\ud83d\udc18 Swift ORM (queries, models, relations, etc) built on PostgreSQL.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/fluent-postgresql.git\n,\n \nfrom\n:\n \n1.0.0-rc\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nFluentPostgreSQL\n,\n \n...]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nDon't forget to add the module as a dependency in the \ntargets\n array. Once you have added the dependency, regenerate your Xcode project with the following command:\n\n\nvapor xcode\n\n\n\n\n\nModel\n\n\nNow let's create our first \nPostgreSQLModel\n. Models represent tables in your PostgreSQL database and they are the primary method of interacting with your data. \n\n\nimport\n \nFluentPostgreSQL\n\n\nimport\n \nVapor\n\n\n\n/// A simple user.\n\n\nfinal\n \nclass\n \nUser\n:\n \nPostgreSQLModel\n \n{\n\n    \n/// The unique identifier for this user.\n\n    \nvar\n \nid\n:\n \nInt\n?\n\n\n    \n/// The user\ns full name.\n\n    \nvar\n \nname\n:\n \nString\n\n\n    \n/// The user\ns current age in years.\n\n    \nvar\n \nage\n:\n \nInt\n\n\n    \n/// Creates a new user.\n\n    \ninit\n(\nid\n:\n \nInt\n?\n \n=\n \nnil\n,\n \nname\n:\n \nString\n,\n \nage\n:\n \nInt\n)\n \n{\n\n        \nself\n.\nid\n \n=\n \nid\n\n        \nself\n.\nname\n \n=\n \nname\n\n        \nself\n.\nage\n \n=\n \nage\n\n    \n}\n\n\n}\n\n\n\n\n\n\nThe example above shows a \nPostgreSQLModel\n for a simple model representing a user. You can make both \nstruct\ns and \nclass\nes a model. You can even conform types that come from external modules. The only requirement is that these types conform to \nCodable\n, which must be declared on the base type for synthesized (automatic) conformance.\n\n\nStandard practice with PostgreSQL databases is using an auto-generated \nINTEGER\n for creating and storing unique identifiers in the \nid\n column. It's also possible to use \nUUID\ns or even \nString\ns for your identifiers. There are convenience protocol for that. \n\n\n\n\n\n\n\n\nprotocol\n\n\ntype\n\n\nkey\n\n\n\n\n\n\n\n\n\n\nPostgreSQLModel\n\n\nInt\n\n\nid\n\n\n\n\n\n\nPostgreSQLUUIDModel\n\n\nUUID\n\n\nid\n\n\n\n\n\n\nPostgreSQLStringModel\n\n\nString\n\n\nid\n\n\n\n\n\n\n\n\n\n\nSeealso\n\n\nTake a look at \nFluent \n Model\n for more information on creating models with custom ID types and keys.\n\n\n\n\nMigration\n\n\nAll of your models (with some rare exceptions) should have a corresponding table\nor \nschema\nin your database. You can use a \nFluent \n Migration\n to automatically generate this schema in a testable, maintainable way. Fluent makes it easy to automatically generate a migration for your model\n\n\n\n\nTip\n\n\nIf you are creating models to represent an existing table or database, you can skip this step.\n\n\n\n\n/// Allows `User` to be used as a migration.\n\n\nextension\n \nUser\n:\n \nMigration\n \n{\n \n}\n\n\n\n\n\n\nThat's all it takes. Fluent uses Codable to analyze your model and will attempt to create the best possible schema for it.\n\n\nTake a look at \nFluent \n Migration\n if you are interested in customizing this migration.\n\n\nConfigure\n\n\nThe final step is to configure your database. At a minimum, this requires adding two things to your \nconfigure.swift\n file.\n\n\n\n\nFluentPostgreSQLProvider\n\n\nMigrationConfig\n\n\n\n\nLet's take a look.\n\n\nimport\n \nFluentPostgreSQL\n\n\n\n/// ...\n\n\n\n/// Register providers first\n\n\ntry\n \nservices\n.\nregister\n(\nFluentPostgreSQLProvider\n())\n\n\n\n/// Configure migrations\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmodel\n:\n \nUser\n.\nself\n,\n \ndatabase\n:\n \n.\npsql\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n/// Other services....\n\n\n\n\n\n\nRegistering the provider will add all of the services required for Fluent PostgreSQL to work properly. It also includes a default database config struct that uses typical development environment credentials. \n\n\nYou can of course override this config struct if you have non-standard credentials.\n\n\n/// Register custom PostgreSQL Config\n\n\nlet\n \npsqlConfig\n \n=\n \nPostgreSQLDatabaseConfig\n(\nhostname\n:\n \nlocalhost\n,\n \nport\n:\n \n5432\n,\n \nusername\n:\n \nvapor\n)\n\n\nservices\n.\nregister\n(\npsqlConfig\n)\n\n\n\n\n\n\nOnce you have the \nMigrationConfig\n added, you should be able to run your application and see the following:\n\n\nMigrating psql DB\nMigrations \ncomplete\n\nServer starting on http://localhost:8080\n\n\n\n\n\nQuery\n\n\nNow that you have created a model and a corresponding schema in your database, let's make your first query.\n\n\nrouter\n.\nget\n(\nusers\n)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nUser\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n}\n\n\n\n\n\n\nIf you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent PostgreSQL model and migration working.\n\n\nConnection\n\n\nWith Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a \"raw query\".\n\n\nLet's take a look at a raw PostgreSQL query.\n\n\nrouter\n.\nget\n(\npsql-version\n)\n \n{\n \nreq\n \n-\n \nFuture\nString\n \nin\n\n    \nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\npsql\n)\n \n{\n \nconn\n \nin\n\n        \nreturn\n \ntry\n \nconn\n.\nquery\n(\nselect version() as v;\n).\nmap\n(\nto\n:\n \nString\n.\nself\n)\n \n{\n \nrows\n \nin\n\n            \nreturn\n \ntry\n \nrows\n[\n0\n].\nfirstValue\n(\nforColumn\n:\n \nv\n)?.\ndecode\n(\nString\n.\nself\n)\n \n??\n \nn/a\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nIn the above example, \nwithPooledConnection(to:)\n is used to create a connection to the database identified by \n.psql\n. This is the default database identifier. See \nFluent \n Database\n to learn more.\n\n\nOnce we have the \nPostgreSQLConnection\n, we can perform a query on it. You can learn more about the methods available in \nPostgreSQL \n Core\n.", 
            "title": "Fluent PostgreSQL"
        }, 
        {
            "location": "/postgresql/fluent/#fluent-postgresql", 
            "text": "Fluent PostgreSQL ( vapor/fluent-postgresql ) is a type-safe, fast, and easy-to-use ORM for PostgreSQL built on top of  Fluent .   Seealso  The Fluent PostgreSQL package is built on top of  Fluent  and the pure Swift, NIO-based  PostgreSQL core . You should refer to their guides for more information about subjects not covered here.", 
            "title": "Fluent PostgreSQL"
        }, 
        {
            "location": "/postgresql/fluent/#getting-started", 
            "text": "This section will show you how to add Fluent PostgreSQL to your project and create your first  PostgreSQLModel .", 
            "title": "Getting Started"
        }, 
        {
            "location": "/postgresql/fluent/#package", 
            "text": "The first step to using Fluent PostgreSQL is adding it as a dependency to your project in your SPM package manifest file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   MyApp , \n     dependencies :   [ \n         /// Any other dependencies ... \n\n         // \ud83d\udd8b\ud83d\udc18 Swift ORM (queries, models, relations, etc) built on PostgreSQL. \n         . package ( url :   https://github.com/vapor/fluent-postgresql.git ,   from :   1.0.0-rc ), \n     ], \n     targets :   [ \n         . target ( name :   App ,   dependencies :   [ FluentPostgreSQL ,   ...]), \n         . target ( name :   Run ,   dependencies :   [ App ]), \n         . testTarget ( name :   AppTests ,   dependencies :   [ App ]), \n     ]  )   Don't forget to add the module as a dependency in the  targets  array. Once you have added the dependency, regenerate your Xcode project with the following command:  vapor xcode", 
            "title": "Package"
        }, 
        {
            "location": "/postgresql/fluent/#model", 
            "text": "Now let's create our first  PostgreSQLModel . Models represent tables in your PostgreSQL database and they are the primary method of interacting with your data.   import   FluentPostgreSQL  import   Vapor  /// A simple user.  final   class   User :   PostgreSQLModel   { \n     /// The unique identifier for this user. \n     var   id :   Int ? \n\n     /// The user s full name. \n     var   name :   String \n\n     /// The user s current age in years. \n     var   age :   Int \n\n     /// Creates a new user. \n     init ( id :   Int ?   =   nil ,   name :   String ,   age :   Int )   { \n         self . id   =   id \n         self . name   =   name \n         self . age   =   age \n     }  }   The example above shows a  PostgreSQLModel  for a simple model representing a user. You can make both  struct s and  class es a model. You can even conform types that come from external modules. The only requirement is that these types conform to  Codable , which must be declared on the base type for synthesized (automatic) conformance.  Standard practice with PostgreSQL databases is using an auto-generated  INTEGER  for creating and storing unique identifiers in the  id  column. It's also possible to use  UUID s or even  String s for your identifiers. There are convenience protocol for that.      protocol  type  key      PostgreSQLModel  Int  id    PostgreSQLUUIDModel  UUID  id    PostgreSQLStringModel  String  id      Seealso  Take a look at  Fluent   Model  for more information on creating models with custom ID types and keys.", 
            "title": "Model"
        }, 
        {
            "location": "/postgresql/fluent/#migration", 
            "text": "All of your models (with some rare exceptions) should have a corresponding table or  schema in your database. You can use a  Fluent   Migration  to automatically generate this schema in a testable, maintainable way. Fluent makes it easy to automatically generate a migration for your model   Tip  If you are creating models to represent an existing table or database, you can skip this step.   /// Allows `User` to be used as a migration.  extension   User :   Migration   {   }   That's all it takes. Fluent uses Codable to analyze your model and will attempt to create the best possible schema for it.  Take a look at  Fluent   Migration  if you are interested in customizing this migration.", 
            "title": "Migration"
        }, 
        {
            "location": "/postgresql/fluent/#configure", 
            "text": "The final step is to configure your database. At a minimum, this requires adding two things to your  configure.swift  file.   FluentPostgreSQLProvider  MigrationConfig   Let's take a look.  import   FluentPostgreSQL  /// ...  /// Register providers first  try   services . register ( FluentPostgreSQLProvider ())  /// Configure migrations  var   migrations   =   MigrationConfig ()  migrations . add ( model :   User . self ,   database :   . psql )  services . register ( migrations )  /// Other services....   Registering the provider will add all of the services required for Fluent PostgreSQL to work properly. It also includes a default database config struct that uses typical development environment credentials.   You can of course override this config struct if you have non-standard credentials.  /// Register custom PostgreSQL Config  let   psqlConfig   =   PostgreSQLDatabaseConfig ( hostname :   localhost ,   port :   5432 ,   username :   vapor )  services . register ( psqlConfig )   Once you have the  MigrationConfig  added, you should be able to run your application and see the following:  Migrating psql DB\nMigrations  complete \nServer starting on http://localhost:8080", 
            "title": "Configure"
        }, 
        {
            "location": "/postgresql/fluent/#query", 
            "text": "Now that you have created a model and a corresponding schema in your database, let's make your first query.  router . get ( users )   {   req   in \n     return   User . query ( on :   req ). all ()  }   If you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent PostgreSQL model and migration working.", 
            "title": "Query"
        }, 
        {
            "location": "/postgresql/fluent/#connection", 
            "text": "With Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a \"raw query\".  Let's take a look at a raw PostgreSQL query.  router . get ( psql-version )   {   req   -   Future String   in \n     return   req . withPooledConnection ( to :   . psql )   {   conn   in \n         return   try   conn . query ( select version() as v; ). map ( to :   String . self )   {   rows   in \n             return   try   rows [ 0 ]. firstValue ( forColumn :   v )?. decode ( String . self )   ??   n/a \n         } \n     }  }   In the above example,  withPooledConnection(to:)  is used to create a connection to the database identified by  .psql . This is the default database identifier. See  Fluent   Database  to learn more.  Once we have the  PostgreSQLConnection , we can perform a query on it. You can learn more about the methods available in  PostgreSQL   Core .", 
            "title": "Connection"
        }, 
        {
            "location": "/postgresql/core/", 
            "text": "PostgreSQL Core\n\n\nPostgreSQL (\nvapor/postgresql\n) is a pure-Swift (no \nlibpq\n dependency), event-driven, non-blocking driver for PostgreSQL. It's built on top of the \nSwiftNIO\n networking library.\n\n\n\n\nSeealso\n\n\nThe higher-level, Fluent PostgreSQL ORM guide is located at \nPostgreSQL \n Fluent\n\n\n\n\nUsing just the PostgreSQL package for your project may be a good idea if any of the following are true.\n\n\n\n\nYou have an existing DB with non-standard structure.\n\n\nYou rely heavily on custom or complex SQL queries.\n\n\nYou just plain don't like ORMs.\n\n\n\n\nPostgreSQL core is built on top of DatabaseKit which provides some conveniences like connection pooling and integrations with Vapor's \nServices\n architecture.\n\n\n\n\nTip\n\n\nEven if you do choose to use \nFluent PostgreSQL\n, all of the features of PostgreSQL core will be available to you.\n\n\n\n\nGetting Started\n\n\nLet's take a look at how you can get started using PostgreSQL core.\n\n\nPackage\n\n\nThe first step to using PostgreSQL core is adding it as a dependency to your project in your SPM package manifest file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nMyApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n/// Any other dependencies ...\n\n\n        \n// \ud83d\udc18 Non-blocking, event-driven Swift client for PostgreSQL.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/postgresql.git\n,\n \nfrom\n:\n \n1.0.0-rc\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nPostgreSQL\n,\n \n...]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nDon't forget to add the module as a dependency in the \ntargets\n array. Once you have added the dependency, regenerate your Xcode project with the following command:\n\n\nvapor xcode\n\n\n\n\n\nConfig\n\n\nThe next step is to configure the database in your \nconfigure.swift\n file.\n\n\nimport\n \nPostgreSQL\n\n\n\n/// ...\n\n\n\n/// Register providers first\n\n\ntry\n \nservices\n.\nregister\n(\nPostgreSQLProvider\n())\n\n\n\n\n\n\nRegistering the provider will add all of the services required for PostgreSQL to work properly. It also includes a default database config struct that uses typical development environment credentials. \n\n\nYou can of course override this config struct if you have non-standard credentials.\n\n\n/// Register custom PostgreSQL Config\n\n\nlet\n \npsqlConfig\n \n=\n \nPostgreSQLDatabaseConfig\n(\nhostname\n:\n \nlocalhost\n,\n \nport\n:\n \n5432\n,\n \nusername\n:\n \nvapor\n)\n\n\nservices\n.\nregister\n(\npsqlConfig\n)\n\n\n\n\n\n\nQuery\n\n\nNow that the database is configured, you can make your first query.\n\n\nrouter\n.\nget\n(\npsql-version\n)\n \n{\n \nreq\n \n-\n \nFuture\nString\n \nin\n\n    \nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\npsql\n)\n \n{\n \nconn\n \nin\n\n        \nreturn\n \ntry\n \nconn\n.\nquery\n(\nselect version() as v;\n).\nmap\n(\nto\n:\n \nString\n.\nself\n)\n \n{\n \nrows\n \nin\n\n            \nreturn\n \ntry\n \nrows\n[\n0\n].\nfirstValue\n(\nforColumn\n:\n \nv\n)?.\ndecode\n(\nString\n.\nself\n)\n \n??\n \nn/a\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nVisiting this route should display your PostgreSQL version.\n\n\nConnection\n\n\nA \nPostgreSQLConnection\n is normally created using the \nRequest\n container and can perform two different types of queries.\n\n\nCreate\n\n\nThere are two methods for creating a \nPostgreSQLConnection\n.\n\n\nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\npsql\n)\n \n{\n \nconn\n \nin\n\n    \n/// ...\n\n\n}\n\n\nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\npsql\n)\n \n{\n \nconn\n \nin\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nAs the names imply,  \nwithPooledConnection(to:)\n utilizes a connection pool. \nwithConnection(to:)\n does not. Connection pooling is a great way to ensure your application does not exceed the limits of your database, even under peak load.\n\n\nSimply Query\n\n\nUse \n.simpleQuery(_:)\n to perform a query on your PostgreSQL database that does not bind any parameters. Some queries you send to PostgreSQL may actually require that you use the \nsimpleQuery(_:)\n method instead of the parameterized method. \n\n\n\n\nNote\n\n\nThis method sends and receives data as text-encoded, meaning it is not optimal for transmitting things like integers.\n\n\n\n\nlet\n \nrows\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\npsql\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nsimpleQuery\n(\nSELECT * FROM users;\n)\n\n\n}\n\n\nprint\n(\nrows\n)\n \n// Future\n[[PostgreSQLColumn: PostgreSQLData]]\n\n\n\n\n\n\nYou can also choose to receive each row in a callback, which is great for conserving memory for large queries.\n\n\nlet\n \ndone\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\npsql\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nsimpleQuery\n(\nSELECT * FROM users;\n)\n \n{\n \nrow\n \nin\n\n        \nprint\n(\nrow\n)\n \n// [PostgreSQLColumn: PostgreSQLData]\n\n    \n}\n\n\n}\n\n\nprint\n(\ndone\n)\n \n// Future\nVoid\n\n\n\n\n\n\nParameterized Query\n\n\nPostgreSQL also supports sending parameterized queries (sometimes called prepared statements). This method allows you to insert data placeholders into the SQL string and send the values separately.\n\n\nData sent via parameterized queries is binary encoded, making it more efficient for sending some data types. In general, you should use parameterized queries where ever possible.\n\n\nlet\n \nusers\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\npsql\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \ntry\n \nconn\n.\nquery\n(\nSELECT *  users WHERE name = $1;\n,\n \n[\nVapor\n])\n\n\n}\n\n\nprint\n(\nusers\n)\n \n// Future\n[[PostgreSQLColumn: PostgreSQLData]]\n\n\n\n\n\n\nYou can also provide a callback, similar to simple queries, for handling each row individually.", 
            "title": "PostgreSQL Core"
        }, 
        {
            "location": "/postgresql/core/#postgresql-core", 
            "text": "PostgreSQL ( vapor/postgresql ) is a pure-Swift (no  libpq  dependency), event-driven, non-blocking driver for PostgreSQL. It's built on top of the  SwiftNIO  networking library.   Seealso  The higher-level, Fluent PostgreSQL ORM guide is located at  PostgreSQL   Fluent   Using just the PostgreSQL package for your project may be a good idea if any of the following are true.   You have an existing DB with non-standard structure.  You rely heavily on custom or complex SQL queries.  You just plain don't like ORMs.   PostgreSQL core is built on top of DatabaseKit which provides some conveniences like connection pooling and integrations with Vapor's  Services  architecture.   Tip  Even if you do choose to use  Fluent PostgreSQL , all of the features of PostgreSQL core will be available to you.", 
            "title": "PostgreSQL Core"
        }, 
        {
            "location": "/postgresql/core/#getting-started", 
            "text": "Let's take a look at how you can get started using PostgreSQL core.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/postgresql/core/#package", 
            "text": "The first step to using PostgreSQL core is adding it as a dependency to your project in your SPM package manifest file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   MyApp , \n     dependencies :   [ \n         /// Any other dependencies ... \n\n         // \ud83d\udc18 Non-blocking, event-driven Swift client for PostgreSQL. \n         . package ( url :   https://github.com/vapor/postgresql.git ,   from :   1.0.0-rc ), \n     ], \n     targets :   [ \n         . target ( name :   App ,   dependencies :   [ PostgreSQL ,   ...]), \n         . target ( name :   Run ,   dependencies :   [ App ]), \n         . testTarget ( name :   AppTests ,   dependencies :   [ App ]), \n     ]  )   Don't forget to add the module as a dependency in the  targets  array. Once you have added the dependency, regenerate your Xcode project with the following command:  vapor xcode", 
            "title": "Package"
        }, 
        {
            "location": "/postgresql/core/#config", 
            "text": "The next step is to configure the database in your  configure.swift  file.  import   PostgreSQL  /// ...  /// Register providers first  try   services . register ( PostgreSQLProvider ())   Registering the provider will add all of the services required for PostgreSQL to work properly. It also includes a default database config struct that uses typical development environment credentials.   You can of course override this config struct if you have non-standard credentials.  /// Register custom PostgreSQL Config  let   psqlConfig   =   PostgreSQLDatabaseConfig ( hostname :   localhost ,   port :   5432 ,   username :   vapor )  services . register ( psqlConfig )", 
            "title": "Config"
        }, 
        {
            "location": "/postgresql/core/#query", 
            "text": "Now that the database is configured, you can make your first query.  router . get ( psql-version )   {   req   -   Future String   in \n     return   req . withPooledConnection ( to :   . psql )   {   conn   in \n         return   try   conn . query ( select version() as v; ). map ( to :   String . self )   {   rows   in \n             return   try   rows [ 0 ]. firstValue ( forColumn :   v )?. decode ( String . self )   ??   n/a \n         } \n     }  }   Visiting this route should display your PostgreSQL version.", 
            "title": "Query"
        }, 
        {
            "location": "/postgresql/core/#connection", 
            "text": "A  PostgreSQLConnection  is normally created using the  Request  container and can perform two different types of queries.", 
            "title": "Connection"
        }, 
        {
            "location": "/postgresql/core/#create", 
            "text": "There are two methods for creating a  PostgreSQLConnection .  return   req . withPooledConnection ( to :   . psql )   {   conn   in \n     /// ...  }  return   req . withConnection ( to :   . psql )   {   conn   in \n     /// ...  }   As the names imply,   withPooledConnection(to:)  utilizes a connection pool.  withConnection(to:)  does not. Connection pooling is a great way to ensure your application does not exceed the limits of your database, even under peak load.", 
            "title": "Create"
        }, 
        {
            "location": "/postgresql/core/#simply-query", 
            "text": "Use  .simpleQuery(_:)  to perform a query on your PostgreSQL database that does not bind any parameters. Some queries you send to PostgreSQL may actually require that you use the  simpleQuery(_:)  method instead of the parameterized method.    Note  This method sends and receives data as text-encoded, meaning it is not optimal for transmitting things like integers.   let   rows   =   req . withPooledConnection ( to :   . psql )   {   conn   in \n     return   conn . simpleQuery ( SELECT * FROM users; )  }  print ( rows )   // Future [[PostgreSQLColumn: PostgreSQLData]]   You can also choose to receive each row in a callback, which is great for conserving memory for large queries.  let   done   =   req . withPooledConnection ( to :   . psql )   {   conn   in \n     return   conn . simpleQuery ( SELECT * FROM users; )   {   row   in \n         print ( row )   // [PostgreSQLColumn: PostgreSQLData] \n     }  }  print ( done )   // Future Void", 
            "title": "Simply Query"
        }, 
        {
            "location": "/postgresql/core/#parameterized-query", 
            "text": "PostgreSQL also supports sending parameterized queries (sometimes called prepared statements). This method allows you to insert data placeholders into the SQL string and send the values separately.  Data sent via parameterized queries is binary encoded, making it more efficient for sending some data types. In general, you should use parameterized queries where ever possible.  let   users   =   req . withPooledConnection ( to :   . psql )   {   conn   in \n     return   try   conn . query ( SELECT *  users WHERE name = $1; ,   [ Vapor ])  }  print ( users )   // Future [[PostgreSQLColumn: PostgreSQLData]]   You can also provide a callback, similar to simple queries, for handling each row individually.", 
            "title": "Parameterized Query"
        }, 
        {
            "location": "/redis/getting-started/", 
            "text": "Warning\n\n\nRedis 3.0 is still in beta. Some documentation may be missing or out of date.\n\n\n\n\nRedis\n\n\nRedis is a Redis client library that can communicate with a Redis database.\n\n\nWhat is Redis?\n\n\nRedis is an in-memory data store used as a database, cache and message broker. It supports most common data structures. Redis is most commonly used for caching data such as sessions and notifications (between multiple servers).\n\n\nRedis works as a key-value store, but allows querying the keys, unlike most databases.\n\n\nWith and without Vapor\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/redis.git\n,\n \n.\nupToNextMajor\n(\nfrom\n:\n \n3.0.0\n)),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nRedis\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nIf this is your first time adding a dependency, you should read our introduction to \nPackage.swift\n.\n\n\nUse \nimport Redis\n to access Redis' APIs.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/redis/getting-started/#redis", 
            "text": "Redis is a Redis client library that can communicate with a Redis database.", 
            "title": "Redis"
        }, 
        {
            "location": "/redis/getting-started/#what-is-redis", 
            "text": "Redis is an in-memory data store used as a database, cache and message broker. It supports most common data structures. Redis is most commonly used for caching data such as sessions and notifications (between multiple servers).  Redis works as a key-value store, but allows querying the keys, unlike most databases.", 
            "title": "What is Redis?"
        }, 
        {
            "location": "/redis/getting-started/#with-and-without-vapor", 
            "text": "To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/redis.git ,   . upToNextMajor ( from :   3.0.0 )), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Redis ,   ...   ]) \n     ]  )   If this is your first time adding a dependency, you should read our introduction to  Package.swift .  Use  import Redis  to access Redis' APIs.", 
            "title": "With and without Vapor"
        }, 
        {
            "location": "/redis/basics/", 
            "text": "Redis basic usage\n\n\nTo interact with Redis, you first need to construct a Redis client.\nThe Redis library primarily supports TCP sockets.\n\n\nThis requires a hostname, port and worker. The eventloop will be used for Redis' Socket. The hostname and port have a default. The hostname is defaulted to \nlocalhost\n, and the port to Redis' default port \n6379\n.\n\n\nlet\n \nclient\n \n=\n \ntry\n \nRedisClient\n.\nconnect\n(\non\n:\n \nworker\n)\n \n// Future\nRedisClient\n\n\n\n\n\n\nThe \nconnect\n method will return a future containing the TCP based Redis Client.\n\n\nRedis Data Types\n\n\nRedis has 6 data types:\n\n\n\n\nnull\n\n\nInt\n\n\nError\n\n\nArray\n\n\nBasic String (used for command names and basic replies only)\n\n\nBulk String (used for Strings and binary data blobs)\n\n\n\n\nYou can instantiate one from the static functions and variables on \nRedisData\n.\n\n\nlet\n \nnull\n \n=\n \nRedisData\n.\nnull\n\n\n\nlet\n \nhelloWorld\n \n=\n \nRedisData\n.\nbulkString\n(\nHello World\n)\n\n\n\nlet\n \nthree\n \n=\n \nRedisData\n.\ninteger\n(\n3\n)\n\n\n\nlet\n \noneThroughTen\n \n=\n \nRedisData\n.\narray\n([\n\n  \n.\ninteger\n(\n1\n),\n\n  \n.\ninteger\n(\n2\n),\n\n  \n.\ninteger\n(\n3\n),\n\n  \n.\ninteger\n(\n4\n),\n\n  \n.\ninteger\n(\n5\n),\n\n  \n.\ninteger\n(\n6\n),\n\n  \n.\ninteger\n(\n7\n),\n\n  \n.\ninteger\n(\n8\n),\n\n  \n.\ninteger\n(\n9\n),\n\n  \n.\ninteger\n(\n10\n)\n\n\n])\n\n\n\n\n\n\nThe above is the explicit way of defining Redis Types. You can also use literals in most scenarios:\n\n\nlet\n \narray\n \n=\n \nRedisData\n.\narray\n([\n\n  \n[\n\n    \n1\n,\n \n2\n,\n \n3\n,\n \n4\n,\n \n5\n,\n \n6\n,\n \n7\n,\n \n8\n,\n \n9\n,\n \n10\n\n  \n],\n\n  \nHello World\n,\n\n  \nOne\n,\n\n  \nTwo\n,\n\n  \n.\nnull\n,\n\n  \n.\nnull\n,\n\n  \ntest\n\n\n])\n\n\n\n\n\n\nCRUD using Redis\n\n\nFrom here on it is assumed that your client has been successfully created and is available in the variable \nclient\n as a \nRedisClient\n.\n\n\nCreating a record\n\n\nCreating a record is done using a \nRedisData\n for a value and a key.\n\n\nclient\n.\nset\n(\nworld\n,\n \nforKey\n:\n \nhello\n)\n\n\n\n\n\n\nThis returns a future that'll indicate successful or unsuccessful insertion.\n\n\nReading a record\n\n\nReading a record is similar, only you'll get a warning if you don't use the returned future.\n\n\nThe \nFuture\nRedisData\n for the key \"hello\" will be \"world\" if you created the record as shown above.\n\n\nlet\n \nfutureRecord\n \n=\n \nclient\n.\ngetData\n(\nforKey\n:\n \nhello\n)\n \n// Future\nRedisData\n\n\n\n\n\n\nDeleting a record\n\n\nDeleting a record is similar but allows querying the keys, too.\n\n\nclient\n.\ndelete\n(\nkeys\n:\n \n[\nhello\n])\n\n\n\n\n\n\nWhere the above command will remove the key \"hello\", the next command will delete \nall\n keys from the Redis database.\n\n\nclient\n.\ndelete\n(\nkeys\n:\n \n[\n*\n])", 
            "title": "Basics"
        }, 
        {
            "location": "/redis/basics/#redis-basic-usage", 
            "text": "To interact with Redis, you first need to construct a Redis client.\nThe Redis library primarily supports TCP sockets.  This requires a hostname, port and worker. The eventloop will be used for Redis' Socket. The hostname and port have a default. The hostname is defaulted to  localhost , and the port to Redis' default port  6379 .  let   client   =   try   RedisClient . connect ( on :   worker )   // Future RedisClient   The  connect  method will return a future containing the TCP based Redis Client.", 
            "title": "Redis basic usage"
        }, 
        {
            "location": "/redis/basics/#redis-data-types", 
            "text": "Redis has 6 data types:   null  Int  Error  Array  Basic String (used for command names and basic replies only)  Bulk String (used for Strings and binary data blobs)   You can instantiate one from the static functions and variables on  RedisData .  let   null   =   RedisData . null  let   helloWorld   =   RedisData . bulkString ( Hello World )  let   three   =   RedisData . integer ( 3 )  let   oneThroughTen   =   RedisData . array ([ \n   . integer ( 1 ), \n   . integer ( 2 ), \n   . integer ( 3 ), \n   . integer ( 4 ), \n   . integer ( 5 ), \n   . integer ( 6 ), \n   . integer ( 7 ), \n   . integer ( 8 ), \n   . integer ( 9 ), \n   . integer ( 10 )  ])   The above is the explicit way of defining Redis Types. You can also use literals in most scenarios:  let   array   =   RedisData . array ([ \n   [ \n     1 ,   2 ,   3 ,   4 ,   5 ,   6 ,   7 ,   8 ,   9 ,   10 \n   ], \n   Hello World , \n   One , \n   Two , \n   . null , \n   . null , \n   test  ])", 
            "title": "Redis Data Types"
        }, 
        {
            "location": "/redis/basics/#crud-using-redis", 
            "text": "From here on it is assumed that your client has been successfully created and is available in the variable  client  as a  RedisClient .", 
            "title": "CRUD using Redis"
        }, 
        {
            "location": "/redis/basics/#creating-a-record", 
            "text": "Creating a record is done using a  RedisData  for a value and a key.  client . set ( world ,   forKey :   hello )   This returns a future that'll indicate successful or unsuccessful insertion.", 
            "title": "Creating a record"
        }, 
        {
            "location": "/redis/basics/#reading-a-record", 
            "text": "Reading a record is similar, only you'll get a warning if you don't use the returned future.  The  Future RedisData  for the key \"hello\" will be \"world\" if you created the record as shown above.  let   futureRecord   =   client . getData ( forKey :   hello )   // Future RedisData", 
            "title": "Reading a record"
        }, 
        {
            "location": "/redis/basics/#deleting-a-record", 
            "text": "Deleting a record is similar but allows querying the keys, too.  client . delete ( keys :   [ hello ])   Where the above command will remove the key \"hello\", the next command will delete  all  keys from the Redis database.  client . delete ( keys :   [ * ])", 
            "title": "Deleting a record"
        }, 
        {
            "location": "/redis/custom-commands/", 
            "text": "Custom commands\n\n\nMany commands are not (yet) implemented by the driver using a convenience function. This does not mean the feature/command is not usable.\n\n\n(Almost) all functions listed here\n work out of the box using custom commands.\n\n\nUsage\n\n\nThe Redis client has a \nrun\n function that allows you to run these commands.\n\n\nThe following code demonstrates a \"custom\" implementation for \nGET\n.\n\n\nlet\n \nfuture\n \n=\n \nclient\n.\nrun\n(\ncommand\n:\n \nGET\n,\n \narguments\n:\n \n[\nmy-key\n])\n \n// Future\nRedisData\n\n\n\n\n\n\nThis future will contain the result as specified in the article on the redis command page or an error.", 
            "title": "Custom commands"
        }, 
        {
            "location": "/redis/custom-commands/#custom-commands", 
            "text": "Many commands are not (yet) implemented by the driver using a convenience function. This does not mean the feature/command is not usable.  (Almost) all functions listed here  work out of the box using custom commands.", 
            "title": "Custom commands"
        }, 
        {
            "location": "/redis/custom-commands/#usage", 
            "text": "The Redis client has a  run  function that allows you to run these commands.  The following code demonstrates a \"custom\" implementation for  GET .  let   future   =   client . run ( command :   GET ,   arguments :   [ my-key ])   // Future RedisData   This future will contain the result as specified in the article on the redis command page or an error.", 
            "title": "Usage"
        }, 
        {
            "location": "/redis/pub-sub/", 
            "text": "Publish \n Subscribe\n\n\nRedis' Publish and Subscribe model is really useful for notifications.\n\n\nUse cases\n\n\nPub/sub is used for notifying subscribers of an event.\nA simple and common event for example would be a chat message.\n\n\nA channel consists of a name and group of listeners. Think of it as being \n[String: [Listener]]\n.\nWhen you send a notification to a channel you need to provide a payload.\nEach listener will get a notification consisting of this payload.\n\n\nChannels must be a string. For chat groups, for example, you could use the database identifier.\n\n\nPublishing\n\n\nYou cannot get a list of listeners, but sending a payload will emit the amount of listeners that received the notification.\nSending (publishing) an event is done like so:\n\n\n// Any redis data\n\n\nlet\n \nnotification\n:\n \nRedisData\n \n=\n \nMy-Notification\n\n\n\nclient\n.\npublish\n(\nnotification\n,\n \nto\n:\n \nmy-channel\n)\n\n\n\n\n\n\nIf you want access to the listener count:\n\n\nlet\n \nnotifiedCount\n \n=\n \nclient\n.\npublish\n(\nnotification\n,\n \nto\n:\n \nmy-channel\n)\n \n// Future\nInt\n\n\n\n\n\n\nSubscribing\n\n\nTo subscribe for notifications you're rendering an entire Redis Client useless in exchange for listening to events.\n\n\nA single client can listen to one or more channels, which is provided using a set of unique channel names. The result of subscribing is a \nSubscriptionStream\n.\n\n\nlet\n \nnotifications\n \n=\n \nclient\n.\nsubscribe\n(\nto\n:\n \n[\nsome-notification-channel\n,\n \nother-notification-channel\n])\n\n\n\n\n\n\nIf you try to use the client after subscribing, all operations will fail. These errors are usually emitted through the Future.\n\n\nThis stream will receive messages asynchronously from the point of \ndraining\n. This works like any other async stream.\n\n\nNotifications consist of the channel and payload.\n\n\nnotifications\n.\ndrain\n \n{\n \nnotification\n \nin\n\n  \nprint\n(\nnotification\n.\nchannel\n)\n\n\n  \nlet\n \npayload\n \n=\n \nnotification\n.\npayload\n\n\n  \n// \nTODO:\n Process the payload\n\n\n}", 
            "title": "Publish and Subscribe"
        }, 
        {
            "location": "/redis/pub-sub/#publish-subscribe", 
            "text": "Redis' Publish and Subscribe model is really useful for notifications.", 
            "title": "Publish &amp; Subscribe"
        }, 
        {
            "location": "/redis/pub-sub/#use-cases", 
            "text": "Pub/sub is used for notifying subscribers of an event.\nA simple and common event for example would be a chat message.  A channel consists of a name and group of listeners. Think of it as being  [String: [Listener]] .\nWhen you send a notification to a channel you need to provide a payload.\nEach listener will get a notification consisting of this payload.  Channels must be a string. For chat groups, for example, you could use the database identifier.", 
            "title": "Use cases"
        }, 
        {
            "location": "/redis/pub-sub/#publishing", 
            "text": "You cannot get a list of listeners, but sending a payload will emit the amount of listeners that received the notification.\nSending (publishing) an event is done like so:  // Any redis data  let   notification :   RedisData   =   My-Notification  client . publish ( notification ,   to :   my-channel )   If you want access to the listener count:  let   notifiedCount   =   client . publish ( notification ,   to :   my-channel )   // Future Int", 
            "title": "Publishing"
        }, 
        {
            "location": "/redis/pub-sub/#subscribing", 
            "text": "To subscribe for notifications you're rendering an entire Redis Client useless in exchange for listening to events.  A single client can listen to one or more channels, which is provided using a set of unique channel names. The result of subscribing is a  SubscriptionStream .  let   notifications   =   client . subscribe ( to :   [ some-notification-channel ,   other-notification-channel ])   If you try to use the client after subscribing, all operations will fail. These errors are usually emitted through the Future.  This stream will receive messages asynchronously from the point of  draining . This works like any other async stream.  Notifications consist of the channel and payload.  notifications . drain   {   notification   in \n   print ( notification . channel ) \n\n   let   payload   =   notification . payload \n\n   //  TODO:  Process the payload  }", 
            "title": "Subscribing"
        }, 
        {
            "location": "/redis/pipeline/", 
            "text": "Pipelining\n\n\nPipelining is used for sending multiple commands at once. The performance advantages become apparent when sending a large number of queries. Redis' pipelining cuts down latency by reducing the RTT (Round Trip Time) between the client and server. Pipelining also reduces the amount of IO operations Redis has to perform, this increases the amount of queries per second Redis can handle. \n\n\nUse cases\n\n\nSometimes multiple commands need to be executed at once.  Instead of sending those commands individually in a loop, pipelining allows the commands to be batched and sent in one request. A common scenario might be needing to set a key and increment a count, pipelining those commands would be ideal.\n\n\nEnqueuing Commands\n\n\n \nlet\n \npipeline\n \n=\n \nconnection\n.\nmakePipeline\n()\n\n \nlet\n \nresult\n \n=\n \ntry\n \npipeline\n\n         \n.\nenqueue\n(\ncommand\n:\n \nSET\n,\n \narguments\n:\n \n[\nKEY\n,\n \nVALUE\n])\n\n         \n.\nenqueue\n(\ncommand\n:\n \nINCR\n,\n \narguments\n:\n \n[\nCOUNT\n])\n\n         \n.\nexecute\n()\n \n// Future\n[RedisData]\n\n\n\n\n\n\nNote: Commands will not be executed until execute is called.", 
            "title": "Pipeline"
        }, 
        {
            "location": "/redis/pipeline/#pipelining", 
            "text": "Pipelining is used for sending multiple commands at once. The performance advantages become apparent when sending a large number of queries. Redis' pipelining cuts down latency by reducing the RTT (Round Trip Time) between the client and server. Pipelining also reduces the amount of IO operations Redis has to perform, this increases the amount of queries per second Redis can handle.", 
            "title": "Pipelining"
        }, 
        {
            "location": "/redis/pipeline/#use-cases", 
            "text": "Sometimes multiple commands need to be executed at once.  Instead of sending those commands individually in a loop, pipelining allows the commands to be batched and sent in one request. A common scenario might be needing to set a key and increment a count, pipelining those commands would be ideal.", 
            "title": "Use cases"
        }, 
        {
            "location": "/redis/pipeline/#enqueuing-commands", 
            "text": "let   pipeline   =   connection . makePipeline () \n  let   result   =   try   pipeline \n          . enqueue ( command :   SET ,   arguments :   [ KEY ,   VALUE ]) \n          . enqueue ( command :   INCR ,   arguments :   [ COUNT ]) \n          . execute ()   // Future [RedisData]   Note: Commands will not be executed until execute is called.", 
            "title": "Enqueuing Commands"
        }, 
        {
            "location": "/routing/getting-started/", 
            "text": "Getting Started with Routing\n\n\nRouting (\nvapor/routing\n) is a small framework for routing things like HTTP requests. It lets you register and lookup routes in a router using nested, dynamic path components.\n\n\nFor example, the routing package can help you route a request like the following and collect the values of the dynamic components.\n\n\n/users/:user_id/comments/:comment_id\n\n\n\n\n\nVapor\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nRouting\n APIs when you import \nVapor\n.\n\n\n\n\nTip\n\n\nIf you use Vapor, most of Routing's APIs will be wrapped by more convenient methods. See \nVapor \n Routing\n for more information.\n\n\n\n\nimport\n \nVapor\n\n\n\n\n\n\nStandalone\n\n\nThe Routing package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a routing framework for any Swift project\neven one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/routing.git\n,\n \nfrom\n:\n \n3.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nRouting\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Routing\n to access the APIs.\n\n\n\n\nWarning\n\n\nSome of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Routing package in general.\nVisit the \nAPI Docs\n for Routing-specific API info.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/routing/getting-started/#getting-started-with-routing", 
            "text": "Routing ( vapor/routing ) is a small framework for routing things like HTTP requests. It lets you register and lookup routes in a router using nested, dynamic path components.  For example, the routing package can help you route a request like the following and collect the values of the dynamic components.  /users/:user_id/comments/:comment_id", 
            "title": "Getting Started with Routing"
        }, 
        {
            "location": "/routing/getting-started/#vapor", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  Routing  APIs when you import  Vapor .   Tip  If you use Vapor, most of Routing's APIs will be wrapped by more convenient methods. See  Vapor   Routing  for more information.   import   Vapor", 
            "title": "Vapor"
        }, 
        {
            "location": "/routing/getting-started/#standalone", 
            "text": "The Routing package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a routing framework for any Swift project even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/routing.git ,   from :   3.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Routing ,   ...   ]) \n     ]  )   Use  import Routing  to access the APIs.   Warning  Some of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Routing package in general.\nVisit the  API Docs  for Routing-specific API info.", 
            "title": "Standalone"
        }, 
        {
            "location": "/routing/overview/", 
            "text": "Using Routing\n\n\nRouting (\nvapor/routing\n) is a small framework for routing things like HTTP requests. It lets you register and lookup routes in a router using nested, dynamic path components.\n\n\n\n\nTip\n\n\nIf you use Vapor, most of Routing's APIs will be wrapped by more convenient methods. See [Vapor \u2192 Routing] for more information.\n\n\n\n\nThis guide will show you how to register a static route and a dynamic route and how to use \nParameter\ns.\n\n\nRegister\n\n\nThe first step to routing is to register some routes. Let's take a look at how to do that with a simple router\na \nTrieRouter\nDouble\n which holds numbers. Usually you would store something like HTTP responders, but we'll keep things simple for this example.\n\n\n// Create a router that stores Doubles\n\n\nlet\n \nrouter\n \n=\n \nTrieRouter\n(\nDouble\n.\nself\n)\n\n\n\n// Register some routes and values to the router\n\n\nrouter\n.\nregister\n(\nroute\n:\n \nRoute\n(\npath\n:\n \n[\nfunny\n,\n \nmeaning_of_universe\n],\n \noutput\n:\n \n42\n))\n\n\nrouter\n.\nregister\n(\nroute\n:\n \nRoute\n(\npath\n:\n \n[\nfunny\n,\n \nleet\n],\n \noutput\n:\n \n1337\n))\n\n\nrouter\n.\nregister\n(\nroute\n:\n \nRoute\n(\npath\n:\n \n[\nmath\n,\n \npi\n],\n \noutput\n:\n \n3.14\n))\n\n\n\n// Create empty Parameters to hold dynamic params (none yet)\n\n\nvar\n \nparams\n \n=\n \nParameters\n()\n\n\n\n// Test fetching some routes\n\n\nprint\n(\nrouter\n.\nroute\n(\npath\n:\n \n[\nfun\n,\n \nmeaning_of_universe\n],\n \nparameters\n:\n \nparams\n))\n \n// 42\n\n\nprint\n(\nrouter\n.\nroute\n(\npath\n:\n \n[\nfoo\n],\n \nparameters\n:\n \nparams\n))\n \n// nil\n\n\n\n\n\n\nHere we are using \nregister(...)\n to register routes to our router, then later \nroute(...)\n to fetch them. The \nTrieRouter\n uses a trie (digital tree) internally to make finding value in the router fast.\n\n\nParameter\n\n\nLet's take a look at registering some dynamic path components. These are parts of the path that are variable and whose value should be collected for later use. You will often see this used for situations like show a webpage for a user:\n\n\n/users/:user_id\n\n\n\n\n\nHere is how you would implement that with \nTrieRouter\n. For this example, we will ignore the route output.\n\n\n// Create a route for /users/:user_id\n\n\nlet\n \nuser\n \n=\n \nRoute\n(\npath\n:\n \n[.\nconstant\n(\nusers\n),\n \n.\nparameter\n(\nuser_id\n)],\n \noutput\n:\n \n...)\n\n\n\n// Create a router and register our route\n\n\nlet\n \nrouter\n \n=\n \nTrieRouter\n(...)\n\n\nrouter\n.\nregister\n(\nroute\n:\n \nuser\n)\n\n\n\n// Create empty Parameters to hold dynamic values\n\n\nvar\n \nparams\n \n=\n \nParameters\n()\n\n\n\n// Route the path /users/42\n\n\n_\n \n=\n \nrouter\n.\nroute\n(\npath\n:\n \n[\nusers\n,\n \n42\n],\n \nparameters\n:\n \nparams\n)\n\n\n\n// The params contains our dynamic value!\n\n\nprint\n(\nparams\n)\n \n// [\nuser_id\n: \n42\n]\n\n\n\n\n\n\nNote that the String used for \n.parameter(...)\n will be the key to fetch the value from \nParameters\n.\n\n\nAPI Docs\n\n\nCheck out the \nAPI docs\n for more in-depth information about all of the available parameters and methods.", 
            "title": "Overview"
        }, 
        {
            "location": "/routing/overview/#using-routing", 
            "text": "Routing ( vapor/routing ) is a small framework for routing things like HTTP requests. It lets you register and lookup routes in a router using nested, dynamic path components.   Tip  If you use Vapor, most of Routing's APIs will be wrapped by more convenient methods. See [Vapor \u2192 Routing] for more information.   This guide will show you how to register a static route and a dynamic route and how to use  Parameter s.", 
            "title": "Using Routing"
        }, 
        {
            "location": "/routing/overview/#register", 
            "text": "The first step to routing is to register some routes. Let's take a look at how to do that with a simple router a  TrieRouter Double  which holds numbers. Usually you would store something like HTTP responders, but we'll keep things simple for this example.  // Create a router that stores Doubles  let   router   =   TrieRouter ( Double . self )  // Register some routes and values to the router  router . register ( route :   Route ( path :   [ funny ,   meaning_of_universe ],   output :   42 ))  router . register ( route :   Route ( path :   [ funny ,   leet ],   output :   1337 ))  router . register ( route :   Route ( path :   [ math ,   pi ],   output :   3.14 ))  // Create empty Parameters to hold dynamic params (none yet)  var   params   =   Parameters ()  // Test fetching some routes  print ( router . route ( path :   [ fun ,   meaning_of_universe ],   parameters :   params ))   // 42  print ( router . route ( path :   [ foo ],   parameters :   params ))   // nil   Here we are using  register(...)  to register routes to our router, then later  route(...)  to fetch them. The  TrieRouter  uses a trie (digital tree) internally to make finding value in the router fast.", 
            "title": "Register"
        }, 
        {
            "location": "/routing/overview/#parameter", 
            "text": "Let's take a look at registering some dynamic path components. These are parts of the path that are variable and whose value should be collected for later use. You will often see this used for situations like show a webpage for a user:  /users/:user_id  Here is how you would implement that with  TrieRouter . For this example, we will ignore the route output.  // Create a route for /users/:user_id  let   user   =   Route ( path :   [. constant ( users ),   . parameter ( user_id )],   output :   ...)  // Create a router and register our route  let   router   =   TrieRouter (...)  router . register ( route :   user )  // Create empty Parameters to hold dynamic values  var   params   =   Parameters ()  // Route the path /users/42  _   =   router . route ( path :   [ users ,   42 ],   parameters :   params )  // The params contains our dynamic value!  print ( params )   // [ user_id :  42 ]   Note that the String used for  .parameter(...)  will be the key to fetch the value from  Parameters .", 
            "title": "Parameter"
        }, 
        {
            "location": "/routing/overview/#api-docs", 
            "text": "Check out the  API docs  for more in-depth information about all of the available parameters and methods.", 
            "title": "API Docs"
        }, 
        {
            "location": "/service/getting-started/", 
            "text": "Getting Started with Service\n\n\nService (\nvapor/service\n) is a dependency injection (inversion of control) framework. It allows you to register, configure, and create your application's dependencies in a maintainable way.\n\n\n/// register a service during boot\n\n\nservices\n.\nregister\n(\nPrintLogger\n.\nself\n,\n \nas\n:\n \nLogger\n.\nself\n)\n\n\n\n/// you can then create that service later\n\n\nlet\n \nlogger\n \n=\n \ntry\n \nsomeContainer\n.\nmake\n(\nLogger\n.\nself\n)\n\n\nprint\n(\nlogger\n \nis\n \nPrintLogger\n)\n \n// true\n\n\n\n\n\n\nYou can read more about \ndependency injection\n on Wikipedia. Also be sure to check out the \nGetting Started \n Services\n guide.\n\n\nVapor\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nService\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n\n\n\n\n\n\nStandalone\n\n\nThe Service package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a dependency injection framework for any Swift project\neven one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/service.git\n,\n \nfrom\n:\n \n1.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nService\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Service\n to access the APIs.\n\n\n\n\nWarning\n\n\nSome of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Services package in general.\nVisit the \nAPI Docs\n for Service-specific API info.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/service/getting-started/#getting-started-with-service", 
            "text": "Service ( vapor/service ) is a dependency injection (inversion of control) framework. It allows you to register, configure, and create your application's dependencies in a maintainable way.  /// register a service during boot  services . register ( PrintLogger . self ,   as :   Logger . self )  /// you can then create that service later  let   logger   =   try   someContainer . make ( Logger . self )  print ( logger   is   PrintLogger )   // true   You can read more about  dependency injection  on Wikipedia. Also be sure to check out the  Getting Started   Services  guide.", 
            "title": "Getting Started with Service"
        }, 
        {
            "location": "/service/getting-started/#vapor", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  Service  APIs when you import  Vapor .  import   Vapor", 
            "title": "Vapor"
        }, 
        {
            "location": "/service/getting-started/#standalone", 
            "text": "The Service package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a dependency injection framework for any Swift project even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/service.git ,   from :   1.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Service ,   ...   ]) \n     ]  )   Use  import Service  to access the APIs.   Warning  Some of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Services package in general.\nVisit the  API Docs  for Service-specific API info.", 
            "title": "Standalone"
        }, 
        {
            "location": "/service/services/", 
            "text": "Using Services\n\n\nThis guide will show you how to register, configure, and create your own service. In this example we will be assuming two different \nLogger\n implementations.\n\n\n\n\nPrintLogger\n: Prints logs.\n\n\nFileLogger\n: Saves logs to a file. Already conforms to \nServiceType\n.\n\n\n\n\nRegister\n\n\nLet's take a look at how we can register our \nPrintLogger\n. First you must conform your type to \nService\n. The easiest way to do this is simply adding the conformance in an extension.\n\n\nextension\n \nPrintLogger\n:\n \nService\n \n{\n \n}\n\n\n\n\n\n\nIt's an empty protocol so there should be no missing requirements.\n\n\nFactory\n\n\nNow the service can be registered to the \nServices\n struct. This is usually done in \nconfigure.swift\n.\n\n\nservices\n.\nregister\n(\nLogger\n.\nself\n)\n \n{\n \ncontainer\n \nin\n\n    \nreturn\n \nPrintLogger\n()\n\n\n}\n\n\n\n\n\n\nBy registering the \nPrintLogger\n using a factory (closure) method, we allow the \nContainer\n to dynamically create the service once it is needed. Any \nSubContainer\ns created later can call this method again to create their own \nPrintLogger\ns.\n\n\nService Type\n\n\nTo make registering a service easier, you can conform it to \nServiceType\n.\n\n\nextension\n \nPrintLogger\n:\n \nServiceType\n \n{\n\n    \n/// See `ServiceType`.\n\n    \nstatic\n \nvar\n \nserviceSupports\n:\n \n[\nAny\n.\nType\n]\n \n{\n\n        \nreturn\n \n[\nLogger\n.\nself\n]\n\n    \n}\n\n\n    \n/// See `ServiceType`.\n\n    \nstatic\n \nfunc\n \nmakeService\n(\nfor\n \nworker\n:\n \nContainer\n)\n \nthrows\n \n-\n \nPrintLogger\n \n{\n\n        \nreturn\n \nPrintLogger\n()\n\n    \n}\n\n\n}\n\n\n\n\n\n\nServices conforming to \nServiceType\n can be registered using just the type name. This will automatically conform to \nService\n as well.\n\n\nservices\n.\nregister\n(\nPrintLogger\n.\nself\n)\n\n\n\n\n\n\nInstance\n\n\nYou can also register pre-initialized instances to \nServices\n.\n\n\nservices\n.\nregister\n(\nPrintLogger\n(),\n \nas\n:\n \nLogger\n.\nself\n)\n\n\n\n\n\n\n\n\nWarning\n\n\nIf using reference types (\nclass\n) this method will share the \nsame\n object between all \nContainer\ns and \nSubContainer\ns.\nBe careful to protect against race conditions.\n\n\n\n\nConfigure\n\n\nIf more than one service is registered for a given interface, we will need to choose which service is used.\n\n\nservices\n.\nregister\n(\nPrintLogger\n.\nself\n)\n\n\nservices\n.\nregister\n(\nFileLogger\n.\nself\n)\n\n\n\n\n\n\nAssuming the above services are registered, we can use service \nConfig\n to pick which one we want.\n\n\nswitch\n \nenv\n \n{\n\n\ncase\n \n.\nproduction\n:\n \nconfig\n.\nprefer\n(\nFileLogger\n.\nself\n,\n \nfor\n:\n \nLogger\n.\nself\n)\n\n\ndefault\n:\n \nconfig\n.\nprefer\n(\nPrintLogger\n.\nself\n,\n \nfor\n:\n \nLogger\n.\nself\n)\n\n\n}\n\n\n\n\n\n\nHere we are using the \nEnvironment\n to dynamically prefer a service. This is usually done in \nconfigure.swift\n.\n\n\n\n\nNote\n\n\nYou can also dynamically \nregister\n services based on environment instead of using service config. \nHowever, service config is required for choosing services that come from the framework or a provider.\n\n\n\n\nCreate\n\n\nAfter you have registered your services, you can use a \nContainer\n to create them.\n\n\nlet\n \nlogger\n \n=\n \ntry\n \nsomeContainer\n.\nmake\n(\nLogger\n.\nself\n)\n\n\nlogger\n.\nlog\n(\nHello, world!\n)\n\n\n\n// PrintLogger or FileLogger depending on the container\ns environment\n\n\nprint\n(\ntype\n(\nof\n:\n \nlogger\n))\n \n\n\n\n\n\n\n\nTip\n\n\nUsually the framework will create any required containers for you. You can use \nBasicContainer\n if you want to create one for testing.", 
            "title": "Services"
        }, 
        {
            "location": "/service/services/#using-services", 
            "text": "This guide will show you how to register, configure, and create your own service. In this example we will be assuming two different  Logger  implementations.   PrintLogger : Prints logs.  FileLogger : Saves logs to a file. Already conforms to  ServiceType .", 
            "title": "Using Services"
        }, 
        {
            "location": "/service/services/#register", 
            "text": "Let's take a look at how we can register our  PrintLogger . First you must conform your type to  Service . The easiest way to do this is simply adding the conformance in an extension.  extension   PrintLogger :   Service   {   }   It's an empty protocol so there should be no missing requirements.", 
            "title": "Register"
        }, 
        {
            "location": "/service/services/#factory", 
            "text": "Now the service can be registered to the  Services  struct. This is usually done in  configure.swift .  services . register ( Logger . self )   {   container   in \n     return   PrintLogger ()  }   By registering the  PrintLogger  using a factory (closure) method, we allow the  Container  to dynamically create the service once it is needed. Any  SubContainer s created later can call this method again to create their own  PrintLogger s.", 
            "title": "Factory"
        }, 
        {
            "location": "/service/services/#service-type", 
            "text": "To make registering a service easier, you can conform it to  ServiceType .  extension   PrintLogger :   ServiceType   { \n     /// See `ServiceType`. \n     static   var   serviceSupports :   [ Any . Type ]   { \n         return   [ Logger . self ] \n     } \n\n     /// See `ServiceType`. \n     static   func   makeService ( for   worker :   Container )   throws   -   PrintLogger   { \n         return   PrintLogger () \n     }  }   Services conforming to  ServiceType  can be registered using just the type name. This will automatically conform to  Service  as well.  services . register ( PrintLogger . self )", 
            "title": "Service Type"
        }, 
        {
            "location": "/service/services/#instance", 
            "text": "You can also register pre-initialized instances to  Services .  services . register ( PrintLogger (),   as :   Logger . self )    Warning  If using reference types ( class ) this method will share the  same  object between all  Container s and  SubContainer s.\nBe careful to protect against race conditions.", 
            "title": "Instance"
        }, 
        {
            "location": "/service/services/#configure", 
            "text": "If more than one service is registered for a given interface, we will need to choose which service is used.  services . register ( PrintLogger . self )  services . register ( FileLogger . self )   Assuming the above services are registered, we can use service  Config  to pick which one we want.  switch   env   {  case   . production :   config . prefer ( FileLogger . self ,   for :   Logger . self )  default :   config . prefer ( PrintLogger . self ,   for :   Logger . self )  }   Here we are using the  Environment  to dynamically prefer a service. This is usually done in  configure.swift .   Note  You can also dynamically  register  services based on environment instead of using service config. \nHowever, service config is required for choosing services that come from the framework or a provider.", 
            "title": "Configure"
        }, 
        {
            "location": "/service/services/#create", 
            "text": "After you have registered your services, you can use a  Container  to create them.  let   logger   =   try   someContainer . make ( Logger . self )  logger . log ( Hello, world! )  // PrintLogger or FileLogger depending on the container s environment  print ( type ( of :   logger ))     Tip  Usually the framework will create any required containers for you. You can use  BasicContainer  if you want to create one for testing.", 
            "title": "Create"
        }, 
        {
            "location": "/service/provider/", 
            "text": "Using Providers\n\n\nThe \nProvider\n protocol make it easy to integrate external services into your application. All of Vapor's official packages, like \nFluent\n, use the provider system to expose their services. \n\n\nProviders can:\n\n\n\n\nRegister services to your \nServices\n struct.\n\n\nHook into your \nContainer\n's lifecycle.\n\n\n\n\nRegister\n\n\nOnce you have added a Service-exposing \nSPM dependency\n to your project, adding the provider is easy.\n\n\nimport\n \nFoo\n\n\n\ntry\n \nservices\n.\nregister\n(\nFooProvider\n())\n\n\n\n\n\n\nThis is usually done in \nconfigure.swift\n. \n\n\n\n\nNote\n\n\nYou can search GitHub for the \nvapor-service\n tag for a list of packages that expose services using this method.\n\n\n\n\nCreate\n\n\nCreating a custom provider can be a great way to organize your code. You will also want to create a provider if you are working on a third-party package for Vapor.\n\n\nHere is what a simple provider would look like for the \nLogger\n examples from the \nServices\n section.\n\n\npublic\n \nfinal\n \nclass\n \nLoggerProvider\n:\n \nProvider\n \n{\n\n    \n/// See `Provider`.\n\n    \npublic\n \nfunc\n \nregister\n(\n_\n \nservices\n:\n \ninout\n \nServices\n)\n \nthrows\n \n{\n\n        \nservices\n.\nregister\n(\nPrintLogger\n.\nself\n)\n\n        \nservices\n.\nregister\n(\nFileLogger\n.\nself\n)\n\n    \n}\n\n\n    \n/// See `Provider`.\n\n    \npublic\n \nfunc\n \ndidBoot\n(\n_\n \ncontainer\n:\n \nContainer\n)\n \nthrows\n \n-\n \nFuture\nVoid\n \n{\n\n        \nlet\n \nlogger\n \n=\n \ntry\n \ncontainer\n.\nmake\n(\nLogger\n.\nself\n)\n\n        \nlogger\n.\nlog\n(\nHello from LoggerProvider!\n)\n\n        \nreturn\n \n.\ndone\n(\non\n:\n \ncontainer\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nNow when someone registers the \nLoggerProvider\n to their \nServices\n struct, it will automatically register the print and file loggers. When the container boots, the success message will be printed to verify the provider was added.\n\n\nSee the \nProvider\n protocol's API docs for more information.", 
            "title": "Provider"
        }, 
        {
            "location": "/service/provider/#using-providers", 
            "text": "The  Provider  protocol make it easy to integrate external services into your application. All of Vapor's official packages, like  Fluent , use the provider system to expose their services.   Providers can:   Register services to your  Services  struct.  Hook into your  Container 's lifecycle.", 
            "title": "Using Providers"
        }, 
        {
            "location": "/service/provider/#register", 
            "text": "Once you have added a Service-exposing  SPM dependency  to your project, adding the provider is easy.  import   Foo  try   services . register ( FooProvider ())   This is usually done in  configure.swift .    Note  You can search GitHub for the  vapor-service  tag for a list of packages that expose services using this method.", 
            "title": "Register"
        }, 
        {
            "location": "/service/provider/#create", 
            "text": "Creating a custom provider can be a great way to organize your code. You will also want to create a provider if you are working on a third-party package for Vapor.  Here is what a simple provider would look like for the  Logger  examples from the  Services  section.  public   final   class   LoggerProvider :   Provider   { \n     /// See `Provider`. \n     public   func   register ( _   services :   inout   Services )   throws   { \n         services . register ( PrintLogger . self ) \n         services . register ( FileLogger . self ) \n     } \n\n     /// See `Provider`. \n     public   func   didBoot ( _   container :   Container )   throws   -   Future Void   { \n         let   logger   =   try   container . make ( Logger . self ) \n         logger . log ( Hello from LoggerProvider! ) \n         return   . done ( on :   container ) \n     }  }   Now when someone registers the  LoggerProvider  to their  Services  struct, it will automatically register the print and file loggers. When the container boots, the success message will be printed to verify the provider was added.  See the  Provider  protocol's API docs for more information.", 
            "title": "Create"
        }, 
        {
            "location": "/sql/getting-started/", 
            "text": "Getting Started with SQL\n\n\nSQL (\nvapor/sql\n) is a library for building and serializing SQL queries in Swift. It has an extensible, protocol-based design and supports DQL, DML, and DDL.\n\n\n\n\nTip\n\n\nIf you use Fluent, you will usually not need to build SQL queries manually.\n\n\n\n\nPackage\n\n\nThe SQL package is lightweight, pure Swift, and has no dependencies. This means it can be used as a SQL serialization framework any Swift project\u2014even one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/sql.git\n,\n \nfrom\n:\n \n1.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nSQL\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport SQL\n to access the APIs.\n\n\nThe rest of this guide will give you an overview of what is available in the SQL package. As always, feel free to visit the \nAPI docs\n for more in-depth information.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/sql/getting-started/#getting-started-with-sql", 
            "text": "SQL ( vapor/sql ) is a library for building and serializing SQL queries in Swift. It has an extensible, protocol-based design and supports DQL, DML, and DDL.   Tip  If you use Fluent, you will usually not need to build SQL queries manually.", 
            "title": "Getting Started with SQL"
        }, 
        {
            "location": "/sql/getting-started/#package", 
            "text": "The SQL package is lightweight, pure Swift, and has no dependencies. This means it can be used as a SQL serialization framework any Swift project\u2014even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/sql.git ,   from :   1.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ SQL ,   ...   ]) \n     ]  )   Use  import SQL  to access the APIs.  The rest of this guide will give you an overview of what is available in the SQL package. As always, feel free to visit the  API docs  for more in-depth information.", 
            "title": "Package"
        }, 
        {
            "location": "/sql/overview/", 
            "text": "Using SQL\n\n\nThe SQL library helps you build and serialize SQL queries in Swift. It has an extensible, protocol-based design and supports DQL, DML, and DDL:\n\n\n\n\nDQL\n: Data Query Language (\nSELECT\n)\n\n\nDML\n: Data Manpulation Language (\nINSERT\n, \nDELETE\n, etc)\n\n\nDDL\n: Data Definition Language (\nCREATE\n, \nALTER\n, etc)\n\n\n\n\nThis library's goal is to help you build SQL queries in a type-safe, consistent way. It can be used by ORMs to serialize their data types into SQL. It can also be used to generate SQL in a more Swifty way. The rest of this guide will give you an overview into using the SQL library manually.\n\n\nData Query\n\n\nDQL (data query language) is used to fetch data from one or more tables. This is done via the \nSELECT\n statement. Let's take a look how we would serialize the following SQL query.\n\n\nSELECT\n \n*\n \nFROM\n \nusers\n \nWHERE\n \nname\n \n=\n \n?\n\n\n\n\n\n\nThis query selects all rows from the table \nusers\n where the name is equal to a parameterized value. You can serialize literal values into data queries as well, but parameterization is highly recommended.\n\n\nLet's build this query in Swift.\n\n\n// Create a new data query for the table.\n\n\nvar\n \nusers\n \n=\n \nDataQuery\n(\ntable\n:\n \nusers\n)\n\n\n\n// Create the \nname = ?\n predicate.\n\n\nlet\n \nname\n \n=\n \nDataPredicate\n(\ncolumn\n:\n \nname\n,\n \ncomparison\n:\n \n.\nequal\n,\n \nvalue\n:\n \n.\nplaceholder\n)\n\n\n\n// Add the predicate as a single item (not group) to the query.\n\n\nusers\n.\npredicates\n.\nappend\n(.\npredicate\n(\nname\n))\n\n\n\n// Serialize the query.\n\n\nlet\n \nsql\n \n=\n \nGeneralSQLSerializer\n.\nshared\n.\nserialize\n(\nquery\n:\n \nusers\n)\n\n\nprint\n(\nsql\n)\n \n// \nSELECT * FROM `users` WHERE (`name` = ?)\n\n\n\n\n\n\nHere we are using the shared \nGeneralSQLSerializer\n to serialize the query. You can also implement \ncustom serializers\n.\n\n\nData Manipulation\n\n\nDML (data manipulation language) is used to mutate data in a table. This is done via statements like \nINSERT\n, \nUPDATE\n, and \nDELETE\n. Let's take a look how we would serialize the following SQL query.\n\n\nINSERT\n \nINTO\n \nusers\n \n(\nname\n)\n \nVALUES\n \n(\n?\n)\n\n\n\n\n\n\nThis query inserts a new row into the table \nusers\n where the name is equal to a parameterized value. You can serialize literal values into data manipulation queries as well, but parameterization is highly recommended.\n\n\nLet's build this query in Swift.\n\n\n// Create a new data manipulation query for the table.\n\n\nvar\n \nusers\n \n=\n \nDataManipulationQuery\n(\nstatement\n:\n \n.\ninsert\n,\n \ntable\n:\n \nusers\n)\n\n\n\n// Create the column + value.\n\n\nlet\n \nname\n \n=\n \nDataManipulationColumn\n(\ncolumn\n:\n \nname\n,\n \nvalue\n:\n \n.\nplaceholder\n)\n\n\n\n// Add the column + value to the query.\n\n\nusers\n.\ncolumns\n.\nappend\n(\nname\n)\n\n\n\n// Serialize the query.\n\n\nlet\n \nsql\n \n=\n \nGeneralSQLSerializer\n.\nshared\n.\nserialize\n(\nquery\n:\n \nuser\n)\n\n\nprint\n(\nsql\n)\n \n// \nINSERT INTO `users` (`name`) VALUES (?)\n\n\n\n\n\n\nThat's all it takes to generate an \nINSERT\n query. Let's take a look at how this query would serialize if we use the \n.update\n statement instead.\n\n\n// Change the statement type\n\n\nusers\n.\nstatement\n \n=\n \n.\nupdate\n\n\n\n// Serialize the query.\n\n\nlet\n \nsql\n \n=\n \nGeneralSQLSerializer\n.\nshared\n.\nserialize\n(\nquery\n:\n \nuser\n)\n\n\nprint\n(\nsql\n)\n \n// \nUPDATE `users` SET `name` = ?\n\n\n\n\n\n\nYou can see that SQL has generated an equivalent \nUPDATE\n query with the appropriate syntax.\n\n\nData Definition\n\n\nDDL (data definition language) is used to create, update, and delete schemas in the database. This is done via statements like \nCREATE TABLE\n, \nDROP TABLE\n, etc. Let's take a look at how we would serialize the following SQL query.\n\n\nCREATE\n \nTABLE\n \nusers\n \n(\nid\n \nINTEGER\n \nPRIMARY\n \nKEY\n,\n \nname\n \nTEXT\n)\n\n\n\n\n\n\nThis example is using SQLite-like syntax, but that is not required. Let's generate this query in Swift.\n\n\n// Create a new data definition query for the table.\n\n\nvar\n \nusers\n \n=\n \nDataDefinitionQuery\n(\nstatement\n:\n \n.\ncreate\n,\n \ntable\n:\n \nusers\n)\n\n\n\n// Create and append the id column.\n\n\nlet\n \nid\n \n=\n \nDataDefinitionColumn\n(\nname\n:\n \nid\n,\n \ndataType\n:\n \nINTEGER\n,\n \nattributes\n:\n \n[\nPRIMARY KEY\n])\n\n\nusers\n.\naddColumns\n.\nappend\n(\nid\n)\n\n\n\n// Create and append the name column.\n\n\nlet\n \nname\n \n=\n \nDataDefinitionColumn\n(\nname\n:\n \nname\n,\n \ndataType\n:\n \nTEXT\n)\n\n\nusers\n.\naddColumns\n.\nappend\n(\nname\n)\n\n\n\n// Serialize the query.\n\n\nlet\n \nsql\n \n=\n \nGeneralSQLSerializer\n.\nshared\n.\nserialize\n(\nquery\n:\n \nuser\n)\n\n\nprint\n(\nsql\n)\n \n// \nCREATE TABLE `users` (`id` INTEGER PRIMARY KEY, `name` TEXT)\n\n\n\n\n\n\nThat's all it takes to generate a \nCREATE\n query.\n\n\nSerializer\n\n\nThe default \nGeneralSQLSerializer\n that comes with this library generates a fairly \"standard\" SQL syntax. However, each flavor of SQL (SQLite, MySQL, PostgreSQL, etc) all have specific rules for their syntax. \n\n\nTo deal with this, all serializers are backed by the \nSQLSerializer\n protocol. All serialization methods are defined on this protocol and come with a default implementation. Custom serializers can conform to this protocol and implement only the methods they need to customize. \n\n\nLet's take a look at how we would implement a \nPostgreSQLSerializer\n that uses \n$x\n placeholders instead of \n?\n.\n\n\n/// Postgres-flavor SQL serializer.\n\n\nfinal\n \nclass\n \nPostgreSQLSerializer\n:\n \nSQLSerializer\n \n{\n\n    \n/// Keeps track of the current placeholder count.\n\n    \nvar\n \ncount\n:\n \nInt\n\n\n    \n/// Creates a new `PostgreSQLSerializer`.\n\n    \ninit\n()\n \n{\n\n        \nself\n.\ncount\n \n=\n \n1\n\n    \n}\n\n\n    \n/// See `SQLSerializer`.\n\n    \nfunc\n \nmakePlaceholder\n()\n \n-\n \nString\n \n{\n\n        \ndefer\n \n{\n \ncount\n \n+=\n \n1\n \n}\n\n        \nreturn\n \n$\n\\(\ncount\n)\n\n    \n}\n\n\n}\n\n\n\n\n\n\nHere we've implemented \nPostgreSQLSerializer\n and overriden one method from \nSQLSerializer\n, \nmakePlaceholder()\n.\n\n\nNow let's use this serializer to serialize the \ndata query\n from a previous example.\n\n\n// Data query from previous example\n\n\nlet\n \nusers\n:\n \nDataQuery\n \n=\n \n...\n \n\n\n// Serialize the query.\n\n\nlet\n \nsql\n \n=\n \nPostgreSQLSerializer\n().\nserialize\n(\nquery\n:\n \nusers\n)\n\n\nprint\n(\nsql\n)\n \n// \nSELECT * FROM `users` WHERE (`name` = $1)\n\n\n\n\n\n\nThat's it, congratulations on implementing a custom serializer.\n\n\nAPI Docs\n\n\nCheck out the \nAPI docs\n for more in-depth information about SQL's APIs.", 
            "title": "Overview"
        }, 
        {
            "location": "/sql/overview/#using-sql", 
            "text": "The SQL library helps you build and serialize SQL queries in Swift. It has an extensible, protocol-based design and supports DQL, DML, and DDL:   DQL : Data Query Language ( SELECT )  DML : Data Manpulation Language ( INSERT ,  DELETE , etc)  DDL : Data Definition Language ( CREATE ,  ALTER , etc)   This library's goal is to help you build SQL queries in a type-safe, consistent way. It can be used by ORMs to serialize their data types into SQL. It can also be used to generate SQL in a more Swifty way. The rest of this guide will give you an overview into using the SQL library manually.", 
            "title": "Using SQL"
        }, 
        {
            "location": "/sql/overview/#data-query", 
            "text": "DQL (data query language) is used to fetch data from one or more tables. This is done via the  SELECT  statement. Let's take a look how we would serialize the following SQL query.  SELECT   *   FROM   users   WHERE   name   =   ?   This query selects all rows from the table  users  where the name is equal to a parameterized value. You can serialize literal values into data queries as well, but parameterization is highly recommended.  Let's build this query in Swift.  // Create a new data query for the table.  var   users   =   DataQuery ( table :   users )  // Create the  name = ?  predicate.  let   name   =   DataPredicate ( column :   name ,   comparison :   . equal ,   value :   . placeholder )  // Add the predicate as a single item (not group) to the query.  users . predicates . append (. predicate ( name ))  // Serialize the query.  let   sql   =   GeneralSQLSerializer . shared . serialize ( query :   users )  print ( sql )   //  SELECT * FROM `users` WHERE (`name` = ?)   Here we are using the shared  GeneralSQLSerializer  to serialize the query. You can also implement  custom serializers .", 
            "title": "Data Query"
        }, 
        {
            "location": "/sql/overview/#data-manipulation", 
            "text": "DML (data manipulation language) is used to mutate data in a table. This is done via statements like  INSERT ,  UPDATE , and  DELETE . Let's take a look how we would serialize the following SQL query.  INSERT   INTO   users   ( name )   VALUES   ( ? )   This query inserts a new row into the table  users  where the name is equal to a parameterized value. You can serialize literal values into data manipulation queries as well, but parameterization is highly recommended.  Let's build this query in Swift.  // Create a new data manipulation query for the table.  var   users   =   DataManipulationQuery ( statement :   . insert ,   table :   users )  // Create the column + value.  let   name   =   DataManipulationColumn ( column :   name ,   value :   . placeholder )  // Add the column + value to the query.  users . columns . append ( name )  // Serialize the query.  let   sql   =   GeneralSQLSerializer . shared . serialize ( query :   user )  print ( sql )   //  INSERT INTO `users` (`name`) VALUES (?)   That's all it takes to generate an  INSERT  query. Let's take a look at how this query would serialize if we use the  .update  statement instead.  // Change the statement type  users . statement   =   . update  // Serialize the query.  let   sql   =   GeneralSQLSerializer . shared . serialize ( query :   user )  print ( sql )   //  UPDATE `users` SET `name` = ?   You can see that SQL has generated an equivalent  UPDATE  query with the appropriate syntax.", 
            "title": "Data Manipulation"
        }, 
        {
            "location": "/sql/overview/#data-definition", 
            "text": "DDL (data definition language) is used to create, update, and delete schemas in the database. This is done via statements like  CREATE TABLE ,  DROP TABLE , etc. Let's take a look at how we would serialize the following SQL query.  CREATE   TABLE   users   ( id   INTEGER   PRIMARY   KEY ,   name   TEXT )   This example is using SQLite-like syntax, but that is not required. Let's generate this query in Swift.  // Create a new data definition query for the table.  var   users   =   DataDefinitionQuery ( statement :   . create ,   table :   users )  // Create and append the id column.  let   id   =   DataDefinitionColumn ( name :   id ,   dataType :   INTEGER ,   attributes :   [ PRIMARY KEY ])  users . addColumns . append ( id )  // Create and append the name column.  let   name   =   DataDefinitionColumn ( name :   name ,   dataType :   TEXT )  users . addColumns . append ( name )  // Serialize the query.  let   sql   =   GeneralSQLSerializer . shared . serialize ( query :   user )  print ( sql )   //  CREATE TABLE `users` (`id` INTEGER PRIMARY KEY, `name` TEXT)   That's all it takes to generate a  CREATE  query.", 
            "title": "Data Definition"
        }, 
        {
            "location": "/sql/overview/#serializer", 
            "text": "The default  GeneralSQLSerializer  that comes with this library generates a fairly \"standard\" SQL syntax. However, each flavor of SQL (SQLite, MySQL, PostgreSQL, etc) all have specific rules for their syntax.   To deal with this, all serializers are backed by the  SQLSerializer  protocol. All serialization methods are defined on this protocol and come with a default implementation. Custom serializers can conform to this protocol and implement only the methods they need to customize.   Let's take a look at how we would implement a  PostgreSQLSerializer  that uses  $x  placeholders instead of  ? .  /// Postgres-flavor SQL serializer.  final   class   PostgreSQLSerializer :   SQLSerializer   { \n     /// Keeps track of the current placeholder count. \n     var   count :   Int \n\n     /// Creates a new `PostgreSQLSerializer`. \n     init ()   { \n         self . count   =   1 \n     } \n\n     /// See `SQLSerializer`. \n     func   makePlaceholder ()   -   String   { \n         defer   {   count   +=   1   } \n         return   $ \\( count ) \n     }  }   Here we've implemented  PostgreSQLSerializer  and overriden one method from  SQLSerializer ,  makePlaceholder() .  Now let's use this serializer to serialize the  data query  from a previous example.  // Data query from previous example  let   users :   DataQuery   =   ...   // Serialize the query.  let   sql   =   PostgreSQLSerializer (). serialize ( query :   users )  print ( sql )   //  SELECT * FROM `users` WHERE (`name` = $1)   That's it, congratulations on implementing a custom serializer.", 
            "title": "Serializer"
        }, 
        {
            "location": "/sql/overview/#api-docs", 
            "text": "Check out the  API docs  for more in-depth information about SQL's APIs.", 
            "title": "API Docs"
        }, 
        {
            "location": "/sqlite/getting-started/", 
            "text": "Warning\n\n\nSQLite 3.0 is still in beta. Some documentation may be missing or out of date.\n\n\n\n\nGetting Started with SQLite\n\n\nSQLite\n is a open-source, embedded database. Its simplistic nature makes it a great candiate for prototyping and testing.\n\n\nYou can use SQLite with Vapor (or any server-side Swift framework) by either:\n\n\n\n\nUsing \nFluent SQLite\n ORM.\n\n\nUse just \nSQLite core\n.\n\n\n\n\nWe recommend using the ORM since it does a lot of the hard work for you. Check out the respective guides to learn more.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/sqlite/getting-started/#getting-started-with-sqlite", 
            "text": "SQLite  is a open-source, embedded database. Its simplistic nature makes it a great candiate for prototyping and testing.  You can use SQLite with Vapor (or any server-side Swift framework) by either:   Using  Fluent SQLite  ORM.  Use just  SQLite core .   We recommend using the ORM since it does a lot of the hard work for you. Check out the respective guides to learn more.", 
            "title": "Getting Started with SQLite"
        }, 
        {
            "location": "/sqlite/fluent/", 
            "text": "Fluent SQLite\n\n\nFluent SQLite (\nvapor/fluent-sqlite\n) is a type-safe, fast, and easy-to-use ORM for SQLite built on top of \nFluent\n.\n\n\n\n\nSeealso\n\n\nThe Fluent SQLite package is built on top of \nFluent\n and the pure Swift, NIO-based \nSQLite core\n. You should refer to their guides for more information about subjects not covered here.\n\n\n\n\nGetting Started\n\n\nThis section will show you how to add Fluent SQLite to your project and create your first \nSQLiteModel\n.\n\n\nPackage\n\n\nThe first step to using Fluent SQLite is adding it as a dependency to your project in your SPM package manifest file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nMyApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n/// Any other dependencies ...\n\n\n        \n// \ud83d\udd8b\ud83d\udc2c Swift ORM (queries, models, relations, etc) built on SQLite.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/fluent-sqlite.git\n,\n \nfrom\n:\n \n3.0.0-rc\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nFluentSQLite\n,\n \n...]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nDon't forget to add the module as a dependency in the \ntargets\n array. Once you have added the dependency, regenerate your Xcode project with the following command:\n\n\nvapor xcode\n\n\n\n\n\nModel\n\n\nNow let's create our first \nSQLiteModel\n. Models represent tables in your SQLite database and they are the primary method of interacting with your data. \n\n\n/// A simple user.\n\n\nfinal\n \nclass\n \nUser\n:\n \nSQLiteModel\n \n{\n\n    \n/// The unique identifier for this user.\n\n    \nvar\n \nid\n:\n \nInt\n?\n\n\n    \n/// The user\ns full name.\n\n    \nvar\n \nname\n:\n \nString\n\n\n    \n/// The user\ns current age in years.\n\n    \nvar\n \nage\n:\n \nInt\n\n\n    \n/// Creates a new user.\n\n    \ninit\n(\nid\n:\n \nInt\n?\n \n=\n \nnil\n,\n \nname\n:\n \nString\n,\n \nage\n:\n \nInt\n)\n \n{\n\n        \nself\n.\nid\n \n=\n \nid\n\n        \nself\n.\nname\n \n=\n \nname\n\n        \nself\n.\nage\n \n=\n \nage\n\n    \n}\n\n\n}\n\n\n\n\n\n\nThe example above shows a \nSQLiteModel\n for a simple model representing a user. You can make both \nstruct\ns and \nclass\nes a model. You can even conform types that come from external modules. The only requirement is that these types conform to \nCodable\n, which must be declared on the base type for synthesized (automatic) conformance.\n\n\nStandard practice with SQLite databases is using an auto-generated \nINTEGER\n for creating and storing unique identifiers in the \nid\n column. It's also possible to use \nUUID\ns or even \nString\ns for your identifiers. There are convenience protocol for that. \n\n\n\n\n\n\n\n\nprotocol\n\n\ntype\n\n\nkey\n\n\n\n\n\n\n\n\n\n\nSQLiteModel\n\n\nInt\n\n\nid\n\n\n\n\n\n\nSQLiteUUIDModel\n\n\nUUID\n\n\nid\n\n\n\n\n\n\nSQLiteStringModel\n\n\nString\n\n\nid\n\n\n\n\n\n\n\n\n\n\nSeealso\n\n\nTake a look at \nFluent \n Model\n for more information on creating models with custom ID types and keys.\n\n\n\n\nMigration\n\n\nAll of your models (with some rare exceptions) should have a corresponding table\nor \nschema\nin your database. You can use a \nFluent \n Migration\n to automatically generate this schema in a testable, maintainable way. Fluent makes it easy to automatically generate a migration for your model\n\n\n\n\nTip\n\n\nIf you are creating models to represent an existing table or database, you can skip this step.\n\n\n\n\n/// Allows `User` to be used as a migration.\n\n\nextension\n \nUser\n:\n \nMigration\n \n{\n \n}\n\n\n\n\n\n\nThat's all it takes. Fluent uses Codable to analyze your model and will attempt to create the best possible schema for it.\n\n\nTake a look at \nFluent \n Migration\n if you are interested in customizing this migration.\n\n\nConfigure\n\n\nThe final step is to configure your database. At a minimum, this requires adding two things to your \nconfigure.swift\n file.\n\n\n\n\nFluentSQLiteProvider\n\n\nMigrationConfig\n\n\n\n\nLet's take a look.\n\n\nimport\n \nFluentSQLite\n\n\n\n/// ...\n\n\n\n/// Register providers first\n\n\ntry\n \nservices\n.\nregister\n(\nFluentSQLiteProvider\n())\n\n\n\n/// Configure migrations\n\n\nvar\n \nmigrations\n \n=\n \nMigrationConfig\n()\n\n\nmigrations\n.\nadd\n(\nmodel\n:\n \nUser\n.\nself\n,\n \ndatabase\n:\n \n.\nsqlite\n)\n\n\nservices\n.\nregister\n(\nmigrations\n)\n\n\n\n/// Other services....\n\n\n\n\n\n\nRegistering the provider will add all of the services required for Fluent SQLite to work properly. It also includes a default database config struct that uses typical development environment credentials. \n\n\nYou can of course override this config struct if you have non-standard credentials.\n\n\n/// Register custom SQLite Config\n\n\nlet\n \nsqliteConfig\n \n=\n \nSQLiteDatabaseConfig\n(\nhostname\n:\n \nlocalhost\n,\n \nport\n:\n \n5432\n,\n \nusername\n:\n \nvapor\n)\n\n\nservices\n.\nregister\n(\nsqliteConfig\n)\n\n\n\n\n\n\nOnce you have the \nMigrationConfig\n added, you should be able to run your application and see the following:\n\n\nMigrating sqlite DB\nMigrations \ncomplete\n\nServer starting on http://localhost:8080\n\n\n\n\n\nQuery\n\n\nNow that you have created a model and a corresponding schema in your database, let's make your first query.\n\n\nrouter\n.\nget\n(\nusers\n)\n \n{\n \nreq\n \nin\n\n    \nreturn\n \nUser\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n}\n\n\n\n\n\n\nIf you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent SQLite model and migration working.\n\n\nConnection\n\n\nWith Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a \"raw query\".\n\n\nLet's take a look at a raw SQLite query.\n\n\nrouter\n.\nget\n(\nsqlite-version\n)\n \n{\n \nreq\n \n-\n \nFuture\nString\n \nin\n\n    \nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n        \nreturn\n \ntry\n \nconn\n.\nquery\n(\nselect sqlite_version() as v;\n).\nmap\n(\nto\n:\n \nString\n.\nself\n)\n \n{\n \nrows\n \nin\n\n            \nreturn\n \ntry\n \nrows\n[\n0\n].\nfirstValue\n(\nforColumn\n:\n \nv\n)?.\ndecode\n(\nString\n.\nself\n)\n \n??\n \nn/a\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nIn the above example, \nwithPooledConnection(to:)\n is used to create a connection to the database identified by \n.sqlite\n. This is the default database identifier. See \nFluent \n Database\n to learn more.\n\n\nOnce we have the \nSQLiteConnection\n, we can perform a query on it. You can learn more about the methods available in \nSQLite \n Core\n.", 
            "title": "Fluent SQLite"
        }, 
        {
            "location": "/sqlite/fluent/#fluent-sqlite", 
            "text": "Fluent SQLite ( vapor/fluent-sqlite ) is a type-safe, fast, and easy-to-use ORM for SQLite built on top of  Fluent .   Seealso  The Fluent SQLite package is built on top of  Fluent  and the pure Swift, NIO-based  SQLite core . You should refer to their guides for more information about subjects not covered here.", 
            "title": "Fluent SQLite"
        }, 
        {
            "location": "/sqlite/fluent/#getting-started", 
            "text": "This section will show you how to add Fluent SQLite to your project and create your first  SQLiteModel .", 
            "title": "Getting Started"
        }, 
        {
            "location": "/sqlite/fluent/#package", 
            "text": "The first step to using Fluent SQLite is adding it as a dependency to your project in your SPM package manifest file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   MyApp , \n     dependencies :   [ \n         /// Any other dependencies ... \n\n         // \ud83d\udd8b\ud83d\udc2c Swift ORM (queries, models, relations, etc) built on SQLite. \n         . package ( url :   https://github.com/vapor/fluent-sqlite.git ,   from :   3.0.0-rc ), \n     ], \n     targets :   [ \n         . target ( name :   App ,   dependencies :   [ FluentSQLite ,   ...]), \n         . target ( name :   Run ,   dependencies :   [ App ]), \n         . testTarget ( name :   AppTests ,   dependencies :   [ App ]), \n     ]  )   Don't forget to add the module as a dependency in the  targets  array. Once you have added the dependency, regenerate your Xcode project with the following command:  vapor xcode", 
            "title": "Package"
        }, 
        {
            "location": "/sqlite/fluent/#model", 
            "text": "Now let's create our first  SQLiteModel . Models represent tables in your SQLite database and they are the primary method of interacting with your data.   /// A simple user.  final   class   User :   SQLiteModel   { \n     /// The unique identifier for this user. \n     var   id :   Int ? \n\n     /// The user s full name. \n     var   name :   String \n\n     /// The user s current age in years. \n     var   age :   Int \n\n     /// Creates a new user. \n     init ( id :   Int ?   =   nil ,   name :   String ,   age :   Int )   { \n         self . id   =   id \n         self . name   =   name \n         self . age   =   age \n     }  }   The example above shows a  SQLiteModel  for a simple model representing a user. You can make both  struct s and  class es a model. You can even conform types that come from external modules. The only requirement is that these types conform to  Codable , which must be declared on the base type for synthesized (automatic) conformance.  Standard practice with SQLite databases is using an auto-generated  INTEGER  for creating and storing unique identifiers in the  id  column. It's also possible to use  UUID s or even  String s for your identifiers. There are convenience protocol for that.      protocol  type  key      SQLiteModel  Int  id    SQLiteUUIDModel  UUID  id    SQLiteStringModel  String  id      Seealso  Take a look at  Fluent   Model  for more information on creating models with custom ID types and keys.", 
            "title": "Model"
        }, 
        {
            "location": "/sqlite/fluent/#migration", 
            "text": "All of your models (with some rare exceptions) should have a corresponding table or  schema in your database. You can use a  Fluent   Migration  to automatically generate this schema in a testable, maintainable way. Fluent makes it easy to automatically generate a migration for your model   Tip  If you are creating models to represent an existing table or database, you can skip this step.   /// Allows `User` to be used as a migration.  extension   User :   Migration   {   }   That's all it takes. Fluent uses Codable to analyze your model and will attempt to create the best possible schema for it.  Take a look at  Fluent   Migration  if you are interested in customizing this migration.", 
            "title": "Migration"
        }, 
        {
            "location": "/sqlite/fluent/#configure", 
            "text": "The final step is to configure your database. At a minimum, this requires adding two things to your  configure.swift  file.   FluentSQLiteProvider  MigrationConfig   Let's take a look.  import   FluentSQLite  /// ...  /// Register providers first  try   services . register ( FluentSQLiteProvider ())  /// Configure migrations  var   migrations   =   MigrationConfig ()  migrations . add ( model :   User . self ,   database :   . sqlite )  services . register ( migrations )  /// Other services....   Registering the provider will add all of the services required for Fluent SQLite to work properly. It also includes a default database config struct that uses typical development environment credentials.   You can of course override this config struct if you have non-standard credentials.  /// Register custom SQLite Config  let   sqliteConfig   =   SQLiteDatabaseConfig ( hostname :   localhost ,   port :   5432 ,   username :   vapor )  services . register ( sqliteConfig )   Once you have the  MigrationConfig  added, you should be able to run your application and see the following:  Migrating sqlite DB\nMigrations  complete \nServer starting on http://localhost:8080", 
            "title": "Configure"
        }, 
        {
            "location": "/sqlite/fluent/#query", 
            "text": "Now that you have created a model and a corresponding schema in your database, let's make your first query.  router . get ( users )   {   req   in \n     return   User . query ( on :   req ). all ()  }   If you run your app, and query that route, you should see an empty array returned. Now you just need to add some users! Congratulations on getting your first Fluent SQLite model and migration working.", 
            "title": "Query"
        }, 
        {
            "location": "/sqlite/fluent/#connection", 
            "text": "With Fluent, you always have access to the underlying database driver. Using this underlying driver to perform a query is sometimes called a \"raw query\".  Let's take a look at a raw SQLite query.  router . get ( sqlite-version )   {   req   -   Future String   in \n     return   req . withPooledConnection ( to :   . sqlite )   {   conn   in \n         return   try   conn . query ( select sqlite_version() as v; ). map ( to :   String . self )   {   rows   in \n             return   try   rows [ 0 ]. firstValue ( forColumn :   v )?. decode ( String . self )   ??   n/a \n         } \n     }  }   In the above example,  withPooledConnection(to:)  is used to create a connection to the database identified by  .sqlite . This is the default database identifier. See  Fluent   Database  to learn more.  Once we have the  SQLiteConnection , we can perform a query on it. You can learn more about the methods available in  SQLite   Core .", 
            "title": "Connection"
        }, 
        {
            "location": "/sqlite/core/", 
            "text": "SQLite Core\n\n\nSQLite (\nvapor/sqlite\n) is a wrapper around the \nlibsqlite\n C-library.\n\n\n\n\nSeealso\n\n\nThe higher-level, Fluent SQLite ORM guide is located at \nSQLite \n Fluent\n\n\n\n\nUsing just the SQLite package for your project may be a good idea if any of the following are true.\n\n\n\n\nYou have an existing DB with non-standard structure.\n\n\nYou rely heavily on custom or complex SQL queries.\n\n\nYou just plain don't like ORMs.\n\n\n\n\nSQLite core is built on top of DatabaseKit which provides some conveniences like connection pooling and integrations with Vapor's \nServices\n architecture.\n\n\n\n\nTip\n\n\nEven if you do choose to use \nFluent SQLite\n, all of the features of SQLite core will be available to you.\n\n\n\n\nGetting Started\n\n\nLet's take a look at how you can get started using SQLite core.\n\n\nPackage\n\n\nThe first step to using SQLite core is adding it as a dependency to your project in your SPM package manifest file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nMyApp\n,\n\n    \ndependencies\n:\n \n[\n\n        \n/// Any other dependencies ...\n\n\n        \n// \ud83d\udd35 SQLite 3 wrapper for Swift.\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/sqlite.git\n,\n \nfrom\n:\n \n3.0.0-rc\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n        \n.\ntarget\n(\nname\n:\n \nApp\n,\n \ndependencies\n:\n \n[\nSQLite\n,\n \n...]),\n\n        \n.\ntarget\n(\nname\n:\n \nRun\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n        \n.\ntestTarget\n(\nname\n:\n \nAppTests\n,\n \ndependencies\n:\n \n[\nApp\n]),\n\n    \n]\n\n\n)\n\n\n\n\n\n\nDon't forget to add the module as a dependency in the \ntargets\n array. Once you have added the dependency, regenerate your Xcode project with the following command:\n\n\nvapor xcode\n\n\n\n\n\nConfig\n\n\nThe next step is to configure the database in your \nconfigure.swift\n file.\n\n\nimport\n \nSQLite\n\n\n\n/// ...\n\n\n\n/// Register providers first\n\n\ntry\n \nservices\n.\nregister\n(\nSQLiteProvider\n())\n\n\n\n\n\n\nRegistering the provider will add all of the services required for SQLite to work properly. It also includes a default database config struct that uses an in-memory DB.\n\n\nYou can of course override this config struct if you have non-standard credentials.\n\n\n/// Register custom SQLite Config\n\n\nlet\n \nsqliteConfig\n \n=\n \nSQLiteDatabaseConfig\n(\nstorage\n:\n \n.\nmemory\n)\n\n\nservices\n.\nregister\n(\nsqliteConfig\n)\n\n\n\n\n\n\nQuery\n\n\nNow that the database is configured, you can make your first query.\n\n\nrouter\n.\nget\n(\nsqlite-version\n)\n \n{\n \nreq\n \n-\n \nFuture\nString\n \nin\n\n    \nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n        \nreturn\n \ntry\n \nconn\n.\nquery\n(\nselect sqlite_version() as v;\n).\nmap\n(\nto\n:\n \nString\n.\nself\n)\n \n{\n \nrows\n \nin\n\n            \nreturn\n \ntry\n \nrows\n[\n0\n].\nfirstValue\n(\nforColumn\n:\n \nv\n)?.\ndecode\n(\nString\n.\nself\n)\n \n??\n \nn/a\n\n        \n}\n\n    \n}\n\n\n}\n\n\n\n\n\n\nVisiting this route should display your SQLite version.\n\n\nConnection\n\n\nA \nSQLiteConnection\n is normally created using the \nRequest\n container and can perform two different types of queries.\n\n\nCreate\n\n\nThere are two methods for creating a \nSQLiteConnection\n.\n\n\nreturn\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n    \n/// ...\n\n\n}\n\n\nreturn\n \nreq\n.\nwithConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n    \n/// ...\n\n\n}\n\n\n\n\n\n\nAs the names imply,  \nwithPooledConnection(to:)\n utilizes a connection pool. \nwithConnection(to:)\n does not. Connection pooling is a great way to ensure your application does not exceed the limits of your database, even under peak load.\n\n\nSimply Query\n\n\nUse \n.simpleQuery(_:)\n to perform a query on your SQLite database that does not bind any parameters. Some queries you send to SQLite may actually require that you use the \nsimpleQuery(_:)\n method instead of the parameterized method. \n\n\n\n\nNote\n\n\nThis method sends and receives data as text-encoded, meaning it is not optimal for transmitting things like integers.\n\n\n\n\nlet\n \nrows\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nsimpleQuery\n(\nSELECT * FROM users;\n)\n\n\n}\n\n\nprint\n(\nrows\n)\n \n// Future\n[[SQLiteColumn: SQLiteData]]\n\n\n\n\n\n\nYou can also choose to receive each row in a callback, which is great for conserving memory for large queries.\n\n\nlet\n \ndone\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \nconn\n.\nsimpleQuery\n(\nSELECT * FROM users;\n)\n \n{\n \nrow\n \nin\n\n        \nprint\n(\nrow\n)\n \n// [SQLiteColumn: SQLiteData]\n\n    \n}\n\n\n}\n\n\nprint\n(\ndone\n)\n \n// Future\nVoid\n\n\n\n\n\n\nParameterized Query\n\n\nSQLite also supports sending parameterized queries (sometimes called prepared statements). This method allows you to insert data placeholders into the SQL string and send the values separately.\n\n\nData sent via parameterized queries is binary encoded, making it more efficient for sending some data types. In general, you should use parameterized queries where ever possible.\n\n\nlet\n \nusers\n \n=\n \nreq\n.\nwithPooledConnection\n(\nto\n:\n \n.\nsqlite\n)\n \n{\n \nconn\n \nin\n\n    \nreturn\n \ntry\n \nconn\n.\nquery\n(\nSELECT *  users WHERE name = $1;\n,\n \n[\nVapor\n])\n\n\n}\n\n\nprint\n(\nusers\n)\n \n// Future\n[[SQLiteColumn: SQLiteData]]\n\n\n\n\n\n\nYou can also provide a callback, similar to simple queries, for handling each row individually.", 
            "title": "SQLite Core"
        }, 
        {
            "location": "/sqlite/core/#sqlite-core", 
            "text": "SQLite ( vapor/sqlite ) is a wrapper around the  libsqlite  C-library.   Seealso  The higher-level, Fluent SQLite ORM guide is located at  SQLite   Fluent   Using just the SQLite package for your project may be a good idea if any of the following are true.   You have an existing DB with non-standard structure.  You rely heavily on custom or complex SQL queries.  You just plain don't like ORMs.   SQLite core is built on top of DatabaseKit which provides some conveniences like connection pooling and integrations with Vapor's  Services  architecture.   Tip  Even if you do choose to use  Fluent SQLite , all of the features of SQLite core will be available to you.", 
            "title": "SQLite Core"
        }, 
        {
            "location": "/sqlite/core/#getting-started", 
            "text": "Let's take a look at how you can get started using SQLite core.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/sqlite/core/#package", 
            "text": "The first step to using SQLite core is adding it as a dependency to your project in your SPM package manifest file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   MyApp , \n     dependencies :   [ \n         /// Any other dependencies ... \n\n         // \ud83d\udd35 SQLite 3 wrapper for Swift. \n         . package ( url :   https://github.com/vapor/sqlite.git ,   from :   3.0.0-rc ), \n     ], \n     targets :   [ \n         . target ( name :   App ,   dependencies :   [ SQLite ,   ...]), \n         . target ( name :   Run ,   dependencies :   [ App ]), \n         . testTarget ( name :   AppTests ,   dependencies :   [ App ]), \n     ]  )   Don't forget to add the module as a dependency in the  targets  array. Once you have added the dependency, regenerate your Xcode project with the following command:  vapor xcode", 
            "title": "Package"
        }, 
        {
            "location": "/sqlite/core/#config", 
            "text": "The next step is to configure the database in your  configure.swift  file.  import   SQLite  /// ...  /// Register providers first  try   services . register ( SQLiteProvider ())   Registering the provider will add all of the services required for SQLite to work properly. It also includes a default database config struct that uses an in-memory DB.  You can of course override this config struct if you have non-standard credentials.  /// Register custom SQLite Config  let   sqliteConfig   =   SQLiteDatabaseConfig ( storage :   . memory )  services . register ( sqliteConfig )", 
            "title": "Config"
        }, 
        {
            "location": "/sqlite/core/#query", 
            "text": "Now that the database is configured, you can make your first query.  router . get ( sqlite-version )   {   req   -   Future String   in \n     return   req . withPooledConnection ( to :   . sqlite )   {   conn   in \n         return   try   conn . query ( select sqlite_version() as v; ). map ( to :   String . self )   {   rows   in \n             return   try   rows [ 0 ]. firstValue ( forColumn :   v )?. decode ( String . self )   ??   n/a \n         } \n     }  }   Visiting this route should display your SQLite version.", 
            "title": "Query"
        }, 
        {
            "location": "/sqlite/core/#connection", 
            "text": "A  SQLiteConnection  is normally created using the  Request  container and can perform two different types of queries.", 
            "title": "Connection"
        }, 
        {
            "location": "/sqlite/core/#create", 
            "text": "There are two methods for creating a  SQLiteConnection .  return   req . withPooledConnection ( to :   . sqlite )   {   conn   in \n     /// ...  }  return   req . withConnection ( to :   . sqlite )   {   conn   in \n     /// ...  }   As the names imply,   withPooledConnection(to:)  utilizes a connection pool.  withConnection(to:)  does not. Connection pooling is a great way to ensure your application does not exceed the limits of your database, even under peak load.", 
            "title": "Create"
        }, 
        {
            "location": "/sqlite/core/#simply-query", 
            "text": "Use  .simpleQuery(_:)  to perform a query on your SQLite database that does not bind any parameters. Some queries you send to SQLite may actually require that you use the  simpleQuery(_:)  method instead of the parameterized method.    Note  This method sends and receives data as text-encoded, meaning it is not optimal for transmitting things like integers.   let   rows   =   req . withPooledConnection ( to :   . sqlite )   {   conn   in \n     return   conn . simpleQuery ( SELECT * FROM users; )  }  print ( rows )   // Future [[SQLiteColumn: SQLiteData]]   You can also choose to receive each row in a callback, which is great for conserving memory for large queries.  let   done   =   req . withPooledConnection ( to :   . sqlite )   {   conn   in \n     return   conn . simpleQuery ( SELECT * FROM users; )   {   row   in \n         print ( row )   // [SQLiteColumn: SQLiteData] \n     }  }  print ( done )   // Future Void", 
            "title": "Simply Query"
        }, 
        {
            "location": "/sqlite/core/#parameterized-query", 
            "text": "SQLite also supports sending parameterized queries (sometimes called prepared statements). This method allows you to insert data placeholders into the SQL string and send the values separately.  Data sent via parameterized queries is binary encoded, making it more efficient for sending some data types. In general, you should use parameterized queries where ever possible.  let   users   =   req . withPooledConnection ( to :   . sqlite )   {   conn   in \n     return   try   conn . query ( SELECT *  users WHERE name = $1; ,   [ Vapor ])  }  print ( users )   // Future [[SQLiteColumn: SQLiteData]]   You can also provide a callback, similar to simple queries, for handling each row individually.", 
            "title": "Parameterized Query"
        }, 
        {
            "location": "/template-kit/getting-started/", 
            "text": "Getting Started with Template Kit\n\n\nTemplate Kit (\nvapor/template-kit\n) is a framework for implementing templating languages in Swift. It is currently used to power Leaf (\nvapor/leaf\n) and hopefully more languages in the future.\n\n\nTemplate Kit is designed to make implementing a templating language easy by defining a common template structure and handling the entire serialization step.\n\n\n\n\nWarning\n\n\nThese docs are for developers interested in implementing a templating language using Template Kit. See \nLeaf \n Getting Started\n for information about using Leaf.\n\n\n\n\nVapor\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nTemplateKit\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n\n\n\n\n\n\nStandalone\n\n\nThe Template Kit package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a templating framework for any Swift project\neven one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/template-kit.git\n,\n \nfrom\n:\n \n1.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nTemplateKit\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport TemplateKit\n to access the APIs.\n\n\nOverview\n\n\nLet's take a look at how Leaf uses Template Kit to render views.\n\n\nAssume we have a template \ngreeting.leaf\n with the following contents:\n\n\nHello, #capitalize(name)!\n\n\n\n\n\nThis first step in rendering this view is to parse the syntax into an abstract syntax tree (AST). This is the part of view rendering that Leaf is responsible for, since Leaf has a unique syntax.\n\n\nLeaf does this by creating a \nLeafParser\n that conforms to \nTemplateParser\n. \n\n\ngreeting.leaf -\n LeafParser -\n AST\n\n\n\n\n\nIn code, this looks like:\n\n\nfunc\n \nparse\n(\nscanner\n:\n \nTemplateByteScanner\n)\n \nthrows\n \n-\n \n[\nTemplateSyntax\n]\n\n\n\n\n\n\nThe AST for our example \ngreeting.leaf\n file would look something like this:\n\n\n[\n\n    \n.\nraw\n(\ndata\n:\n \nHello. \n),\n \n    \n.\ntag\n(\n\n        \nname\n:\n \ncapitalize\n,\n \n        \nparameters\n:\n \n[.\nidentifier\n(\nname\n)]\n\n    \n),\n\n    \n.\nraw\n(\ndata\n:\n \n!\n),\n \n\n]\n\n\n\n\n\n\nNow that Leaf has created an AST, it's job is done! Template Kit will handle converting this AST into a rendered view. All it needs is a \nTemplateData\n to use for filling in any variables.\n\n\nlet\n \ndata\n \n=\n \nTemplateData\n.\ndictionary\n([\nname\n:\n \nvapor\n])\n\n\n\n\n\n\nThe above data will be combined with the AST and used by the \nTemplateSerializer\n to create a rendered view.\n\n\nAST + Data -\n TemplateSerializer -\n View\n\n\n\n\n\nOur rendered view will look something like:\n\n\nHello, Vapor!\n\n\n\n\n\nAll of these steps are handled by \nLeafRenderer\n which conforms to \nTemplateRenderer\n. A template renderer is simply an object that contains both a parser and a serializer. When you implement one, you will get several helpful extensions from Template Kit for free that help load files and cache parsed ASTs. It's what the end user will use to render views.\n\n\nThe entire pipeline looks like this:\n\n\n                            LeafRenderer\n                                 |\n|----------------------------------------------------------------|\n greeting.leaf -\n LeafParser -\n AST -\n TemplateSerializer -\n View\n                                 ^\n                                /\n                   TemplateData\n\n\n\n\n\nIn code, the \nmethod\n looks like this:\n\n\npublic\n \nfunc\n \nrender\n(\n_\n \npath\n:\n \nString\n,\n \n_\n \ncontext\n:\n \nTemplateData\n)\n \n-\n \nFuture\nView\n\n\n\n\n\n\nCheck out Template Kit's \nAPI docs\n for detailed information about all of the protocols, structs, and classes Template Kit offers.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/template-kit/getting-started/#getting-started-with-template-kit", 
            "text": "Template Kit ( vapor/template-kit ) is a framework for implementing templating languages in Swift. It is currently used to power Leaf ( vapor/leaf ) and hopefully more languages in the future.  Template Kit is designed to make implementing a templating language easy by defining a common template structure and handling the entire serialization step.   Warning  These docs are for developers interested in implementing a templating language using Template Kit. See  Leaf   Getting Started  for information about using Leaf.", 
            "title": "Getting Started with Template Kit"
        }, 
        {
            "location": "/template-kit/getting-started/#vapor", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  TemplateKit  APIs when you import  Vapor .  import   Vapor", 
            "title": "Vapor"
        }, 
        {
            "location": "/template-kit/getting-started/#standalone", 
            "text": "The Template Kit package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a templating framework for any Swift project even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/template-kit.git ,   from :   1.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ TemplateKit ,   ...   ]) \n     ]  )   Use  import TemplateKit  to access the APIs.", 
            "title": "Standalone"
        }, 
        {
            "location": "/template-kit/getting-started/#overview", 
            "text": "Let's take a look at how Leaf uses Template Kit to render views.  Assume we have a template  greeting.leaf  with the following contents:  Hello, #capitalize(name)!  This first step in rendering this view is to parse the syntax into an abstract syntax tree (AST). This is the part of view rendering that Leaf is responsible for, since Leaf has a unique syntax.  Leaf does this by creating a  LeafParser  that conforms to  TemplateParser .   greeting.leaf -  LeafParser -  AST  In code, this looks like:  func   parse ( scanner :   TemplateByteScanner )   throws   -   [ TemplateSyntax ]   The AST for our example  greeting.leaf  file would look something like this:  [ \n     . raw ( data :   Hello.  ),  \n     . tag ( \n         name :   capitalize ,  \n         parameters :   [. identifier ( name )] \n     ), \n     . raw ( data :   ! ),   ]   Now that Leaf has created an AST, it's job is done! Template Kit will handle converting this AST into a rendered view. All it needs is a  TemplateData  to use for filling in any variables.  let   data   =   TemplateData . dictionary ([ name :   vapor ])   The above data will be combined with the AST and used by the  TemplateSerializer  to create a rendered view.  AST + Data -  TemplateSerializer -  View  Our rendered view will look something like:  Hello, Vapor!  All of these steps are handled by  LeafRenderer  which conforms to  TemplateRenderer . A template renderer is simply an object that contains both a parser and a serializer. When you implement one, you will get several helpful extensions from Template Kit for free that help load files and cache parsed ASTs. It's what the end user will use to render views.  The entire pipeline looks like this:                              LeafRenderer\n                                 |\n|----------------------------------------------------------------|\n greeting.leaf -  LeafParser -  AST -  TemplateSerializer -  View\n                                 ^\n                                /\n                   TemplateData  In code, the  method  looks like this:  public   func   render ( _   path :   String ,   _   context :   TemplateData )   -   Future View   Check out Template Kit's  API docs  for detailed information about all of the protocols, structs, and classes Template Kit offers.", 
            "title": "Overview"
        }, 
        {
            "location": "/testing/getting-started/", 
            "text": "Getting Started with Testing\n\n\nComing soon.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/testing/getting-started/#getting-started-with-testing", 
            "text": "Coming soon.", 
            "title": "Getting Started with Testing"
        }, 
        {
            "location": "/url-encoded-form/getting-started/", 
            "text": "Getting Started with URL-Encoded Form\n\n\nURL-Encoded Form (\nvapor/url-encoded-form\n) is a small package that helps you parse and serialize \napplication/x-www-form-urlencoded\n data. URL-encoded forms are a widely-supported encoding on the web. It's most often used for serializing web forms sent via POST requests.\n\n\nThe URL-Encoded Form package makes it easy to use this encoding by integrating directly with \nCodable\n.\n\n\nVapor\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nURLEncodedForm\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n\n\n\n\n\n\nStandalone\n\n\nThe URL-Encoded Form package is lightweight, pure-Swift, and has very few dependencies. This means it can be used to work with \nform-urlencoded\n data for any Swift project\neven one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/url-encoded-form.git\n,\n \nfrom\n:\n \n1.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nURLEncodedForm\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport URLEncodedForm\n to access the APIs.\n\n\n\n\nWarning\n\n\nSome of this guide may contain Vapor-specific APIs, however most of it should be applicable to the URL-Encoded Form package in general.\nVisit the \nAPI Docs\n for specific API info.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/url-encoded-form/getting-started/#getting-started-with-url-encoded-form", 
            "text": "URL-Encoded Form ( vapor/url-encoded-form ) is a small package that helps you parse and serialize  application/x-www-form-urlencoded  data. URL-encoded forms are a widely-supported encoding on the web. It's most often used for serializing web forms sent via POST requests.  The URL-Encoded Form package makes it easy to use this encoding by integrating directly with  Codable .", 
            "title": "Getting Started with URL-Encoded Form"
        }, 
        {
            "location": "/url-encoded-form/getting-started/#vapor", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  URLEncodedForm  APIs when you import  Vapor .  import   Vapor", 
            "title": "Vapor"
        }, 
        {
            "location": "/url-encoded-form/getting-started/#standalone", 
            "text": "The URL-Encoded Form package is lightweight, pure-Swift, and has very few dependencies. This means it can be used to work with  form-urlencoded  data for any Swift project even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/url-encoded-form.git ,   from :   1.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ URLEncodedForm ,   ...   ]) \n     ]  )   Use  import URLEncodedForm  to access the APIs.   Warning  Some of this guide may contain Vapor-specific APIs, however most of it should be applicable to the URL-Encoded Form package in general.\nVisit the  API Docs  for specific API info.", 
            "title": "Standalone"
        }, 
        {
            "location": "/url-encoded-form/overview/", 
            "text": "Using URL-Encoded Form\n\n\nURL-Encoded Form is a widely-supported encoding on the web. It's most often used for serializing web forms sent via POST requests. This encoding is also used to send structured data in URL query strings.\n\n\nIt is a relatively efficient encoding for sending small amounts of data. However, all data must be percent-encoded making this encoding suboptimal for large amounts of data. See the \nMultipart\n encoding if you need to upload things like files.\n\n\n\n\nTip\n\n\nURL-Encoded Form integrates with \nContent\n like all other encoding methods in Vapor. See \nVapor \n Content\n for more information about the \nContent\n protocol. \n\n\n\n\nLet's take a look at how to decode a \napplication/x-www-form-urlencoded\n request. \n\n\nDecode Body\n\n\nMost often, you will be decoding \nform-urlencoded\n-encoded requests from a web form. Let's take a look at what one of these requests might look like. After that, we will take a look at what the HTML form for that request would look like.\n\n\nRequest\n\n\nHere is an example \nform-urlencoded\n-encoded request for creating a new user.\n\n\nPOST\n \n/users\n \nHTTP\n/\n1.1\n\n\nContent-Type\n:\n \napplication/x-www-form-urlencoded\n\n\nname=Vapor\nage=3\nluckyNumbers[]=5\nluckyNumbers[]=7\n\n\n\n\n\nYou can see the \n[]\n notation is used to encode arrays. Your web form will need to use this notation as well.\n\n\nForm\n\n\nThere are many ways to create a \nform-urlencoded\n-encoded request, but the most common is an HTML web form. Here is what the HTML form for this request might have looked like.\n\n\nform\n \nmethod\n=\nPOST\n \naction\n=\n/users\n\n    \ninput\n \ntype\n=\ntext\n \nname\n=\nname\n\n    \ninput\n \ntype\n=\ntext\n \nname\n=\nage\n\n    \ninput\n \ntype\n=\ntext\n \nname\n=\nluckyNumbers[]\n\n    \ninput\n \ntype\n=\ntext\n \nname\n=\nluckyNumbers[]\n  \n\n/\nform\n\n\n\n\n\n\nSince we are not specifying a special \nenctype\n attribute on the \nform\n, the browser will URL-encode the form by default. We are also providing two fields with the same name, \nluckyNumbers[]\n. This will let us send an array of values.\n\n\nContent\n\n\nNow let's take a look at how we would handle this request in Vapor. The first step (as always with \nContent\n) is to create a \nCodable\n struct that represents the data structure.\n\n\nimport\n \nVapor\n\n\n\nstruct\n \nUser\n:\n \nContent\n \n{\n\n    \nvar\n \nname\n:\n \nString\n\n    \nvar\n \nage\n:\n \nInt\n\n    \nvar\n \nluckyNumbers\n:\n \n[\nInt\n]\n\n\n}\n\n\n\n\n\n\nNow that we have our \nUser\n struct, let's decode that request! We can use the \nContentContainer\n to do this easily.\n\n\nrouter\n.\npost\n(\nusers\n)\n \n{\n \nreq\n \n-\n \nFuture\nHTTPStatus\n \nin\n\n    \nreturn\n \ntry\n \nreq\n.\ncontent\n.\ndecode\n(\nUser\n.\nself\n).\nmap\n(\nto\n:\n \nHTTPStatus\n.\nself\n)\n \n{\n \nuser\n \nin\n\n        \nprint\n(\nuser\n.\nname\n)\n \n// \nVapor\n\n        \nprint\n(\nuser\n.\nage\n)\n \n// 3\n\n        \nprint\n(\nuser\n.\nluckyNumbers\n)\n \n// [5, 7]\n\n        \nreturn\n \n.\nok\n\n    \n}\n\n\n}\n\n\n\n\n\n\nNow when you post the form to \n/users\n, you should see the information printed in the console. Nice work!\n\n\nEncode Body\n\n\nAPIs encode \nform-urlencoded\n data much less often than they decode it. However, encoding is just as easy with Vapor. Using our same \nUser\n struct from the previous example, here is how we can encode a \nform-urlencoded\n-encoded response.\n\n\nrouter\n.\nget\n(\nmultipart\n)\n \n{\n \nreq\n \n-\n \nUser\n \nin\n\n    \nlet\n \nres\n \n=\n \nreq\n.\nmakeResponse\n()\n\n    \nlet\n \nuser\n \n=\n \nUser\n(\nname\n:\n \nVapor\n,\n \nage\n:\n \n3\n,\n \nluckyNumbers\n:\n \n[\n5\n,\n \n7\n])\n\n    \nres\n.\ncontent\n.\nencode\n(\nuser\n,\n \nas\n:\n \n.\nurlEncodedForm\n)\n\n    \nreturn\n \nuser\n\n\n}\n\n\n\n\n\n\n\n\nTip\n\n\nIf you set a default \nMediaType\n on your \nContent\n types, then you can return them directly in the route closure.\n\n\n\n\nURL Query\n\n\nURL-Encoded Forms are also useful for sending structured data in the URL query string. This is widely used for sending data via GET requests where HTTP bodies are not allowed.\n\n\nLet's take a look at how we can decode some search parameters from the query string.\n\n\nGET\n \n/users?name=Vapor\nage=3\n \nHTTP\n/\n1.1\n\n\n\n\n\n\nThe first step (as always with \nContent\n) is to create a \nCodable\n struct that represents the data structure.\n\n\nimport\n \nVapor\n\n\n\nstruct\n \nUsersFilters\n:\n \nContent\n \n{\n\n    \nvar\n \nname\n:\n \nString\n?\n\n    \nvar\n \nage\n:\n \nInt\n?\n\n\n}\n\n\n\n\n\n\nHere we are making both \nname\n and \nage\n optional since the route can be called without any flags to return all users.\n\n\nNow that we have a \nCodable\n struct, we can decode the URL query string. The process is almost identical to decoding content, expect we use \nreq.query\n instead of \nreq.content\n.\n\n\nrouter\n.\nget\n(\nusers\n)\n \n{\n \nreq\n \n-\n \nFuture\n[\nUser\n]\n \nin\n\n    \nlet\n \nfilters\n \n=\n \ntry\n \nreq\n.\nquery\n.\ndecode\n(\nUsersFilters\n.\nself\n)\n\n    \nprint\n(\nfilters\n.\nname\n)\n \n// Vapor\n\n    \nprint\n(\nfilters\n.\nage\n)\n \n//  3\n\n    \nreturn\n \n// fetch users with filters\n\n\n}\n\n\n\n\n\n\n\n\nTip\n\n\nDecoding the URL query string is not asynchronous because, unlike HTTP bodies, Vapor can be sure it is available when calling the route closure.", 
            "title": "Overview"
        }, 
        {
            "location": "/url-encoded-form/overview/#using-url-encoded-form", 
            "text": "URL-Encoded Form is a widely-supported encoding on the web. It's most often used for serializing web forms sent via POST requests. This encoding is also used to send structured data in URL query strings.  It is a relatively efficient encoding for sending small amounts of data. However, all data must be percent-encoded making this encoding suboptimal for large amounts of data. See the  Multipart  encoding if you need to upload things like files.   Tip  URL-Encoded Form integrates with  Content  like all other encoding methods in Vapor. See  Vapor   Content  for more information about the  Content  protocol.    Let's take a look at how to decode a  application/x-www-form-urlencoded  request.", 
            "title": "Using URL-Encoded Form"
        }, 
        {
            "location": "/url-encoded-form/overview/#decode-body", 
            "text": "Most often, you will be decoding  form-urlencoded -encoded requests from a web form. Let's take a look at what one of these requests might look like. After that, we will take a look at what the HTML form for that request would look like.", 
            "title": "Decode Body"
        }, 
        {
            "location": "/url-encoded-form/overview/#request", 
            "text": "Here is an example  form-urlencoded -encoded request for creating a new user.  POST   /users   HTTP / 1.1  Content-Type :   application/x-www-form-urlencoded \n\nname=Vapor age=3 luckyNumbers[]=5 luckyNumbers[]=7  You can see the  []  notation is used to encode arrays. Your web form will need to use this notation as well.", 
            "title": "Request"
        }, 
        {
            "location": "/url-encoded-form/overview/#form", 
            "text": "There are many ways to create a  form-urlencoded -encoded request, but the most common is an HTML web form. Here is what the HTML form for this request might have looked like.  form   method = POST   action = /users \n     input   type = text   name = name \n     input   type = text   name = age \n     input   type = text   name = luckyNumbers[] \n     input   type = text   name = luckyNumbers[]    / form   Since we are not specifying a special  enctype  attribute on the  form , the browser will URL-encode the form by default. We are also providing two fields with the same name,  luckyNumbers[] . This will let us send an array of values.", 
            "title": "Form"
        }, 
        {
            "location": "/url-encoded-form/overview/#content", 
            "text": "Now let's take a look at how we would handle this request in Vapor. The first step (as always with  Content ) is to create a  Codable  struct that represents the data structure.  import   Vapor  struct   User :   Content   { \n     var   name :   String \n     var   age :   Int \n     var   luckyNumbers :   [ Int ]  }   Now that we have our  User  struct, let's decode that request! We can use the  ContentContainer  to do this easily.  router . post ( users )   {   req   -   Future HTTPStatus   in \n     return   try   req . content . decode ( User . self ). map ( to :   HTTPStatus . self )   {   user   in \n         print ( user . name )   //  Vapor \n         print ( user . age )   // 3 \n         print ( user . luckyNumbers )   // [5, 7] \n         return   . ok \n     }  }   Now when you post the form to  /users , you should see the information printed in the console. Nice work!", 
            "title": "Content"
        }, 
        {
            "location": "/url-encoded-form/overview/#encode-body", 
            "text": "APIs encode  form-urlencoded  data much less often than they decode it. However, encoding is just as easy with Vapor. Using our same  User  struct from the previous example, here is how we can encode a  form-urlencoded -encoded response.  router . get ( multipart )   {   req   -   User   in \n     let   res   =   req . makeResponse () \n     let   user   =   User ( name :   Vapor ,   age :   3 ,   luckyNumbers :   [ 5 ,   7 ]) \n     res . content . encode ( user ,   as :   . urlEncodedForm ) \n     return   user  }    Tip  If you set a default  MediaType  on your  Content  types, then you can return them directly in the route closure.", 
            "title": "Encode Body"
        }, 
        {
            "location": "/url-encoded-form/overview/#url-query", 
            "text": "URL-Encoded Forms are also useful for sending structured data in the URL query string. This is widely used for sending data via GET requests where HTTP bodies are not allowed.  Let's take a look at how we can decode some search parameters from the query string.  GET   /users?name=Vapor age=3   HTTP / 1.1   The first step (as always with  Content ) is to create a  Codable  struct that represents the data structure.  import   Vapor  struct   UsersFilters :   Content   { \n     var   name :   String ? \n     var   age :   Int ?  }   Here we are making both  name  and  age  optional since the route can be called without any flags to return all users.  Now that we have a  Codable  struct, we can decode the URL query string. The process is almost identical to decoding content, expect we use  req.query  instead of  req.content .  router . get ( users )   {   req   -   Future [ User ]   in \n     let   filters   =   try   req . query . decode ( UsersFilters . self ) \n     print ( filters . name )   // Vapor \n     print ( filters . age )   //  3 \n     return   // fetch users with filters  }    Tip  Decoding the URL query string is not asynchronous because, unlike HTTP bodies, Vapor can be sure it is available when calling the route closure.", 
            "title": "URL Query"
        }, 
        {
            "location": "/validation/getting-started/", 
            "text": "Getting Started with Validation\n\n\nValidation (\nvapor/validation\n) is a framework for validating data sent to your application. It can help validate things like names, emails and more. It is also extensible, allowing you to easily create custom validators.\n\n\nThe rest of this guide will show you how to add and import the \nValidation\n module. For more information on using this package, check out \nValidation \n Overview\n.\n\n\nVapor\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nValidation\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n\n\n\n\n\n\nStandalone\n\n\nThe Service package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a validation framework for any Swift project\neven one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/validation.git\n,\n \nfrom\n:\n \n2.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nValidation\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Validation\n to access the APIs.\n\n\n\n\nWarning\n\n\nSome of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Validation package in general.\nVisit the \nAPI Docs\n for Validation-specific API info.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/validation/getting-started/#getting-started-with-validation", 
            "text": "Validation ( vapor/validation ) is a framework for validating data sent to your application. It can help validate things like names, emails and more. It is also extensible, allowing you to easily create custom validators.  The rest of this guide will show you how to add and import the  Validation  module. For more information on using this package, check out  Validation   Overview .", 
            "title": "Getting Started with Validation"
        }, 
        {
            "location": "/validation/getting-started/#vapor", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  Validation  APIs when you import  Vapor .  import   Vapor", 
            "title": "Vapor"
        }, 
        {
            "location": "/validation/getting-started/#standalone", 
            "text": "The Service package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a validation framework for any Swift project even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/validation.git ,   from :   2.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Validation ,   ...   ]) \n     ]  )   Use  import Validation  to access the APIs.   Warning  Some of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Validation package in general.\nVisit the  API Docs  for Validation-specific API info.", 
            "title": "Standalone"
        }, 
        {
            "location": "/validation/overview/", 
            "text": "Validation Overview\n\n\nValidation is a framework for validating data sent to your application. It can help validate things like names, emails and more. It is also extensible, allowing you to easily create custom validators.\n\n\nSwift \n Codable\n\n\nSwift's strong type system and \nCodable\n take care of most of the basic validation that web apps need to do. \n\n\nstruct\n \nUser\n:\n \nCodable\n \n{\n\n    \nvar\n \nid\n:\n \nUUID\n?\n\n    \nvar\n \nname\n:\n \nString\n\n    \nvar\n \nage\n:\n \nInt\n\n    \nvar\n \nemail\n:\n \nString\n?\n\n\n}\n\n\n\n\n\n\nFor example, when you decode the above \nUser\n model, Swift will automatically ensure the following:\n\n\n\n\nid\n is a valid \nUUID\n or is \nnil\n.\n\n\nname\n is a valid \nString\n and is \nnot\n \nnil\n.\n\n\nage\n is a valid \nInt\n and is \nnot\n \nnil\n.\n\n\nemail\n is a valid \nString\n or is \nnil\n.\n\n\n\n\nThis is a great first step, but there is still room for improvement here. Here are some examples of things Swift and \nCodable\n would not mind, but are not ideal:\n\n\n\n\nname\n is empty string \n\"\"\n\n\nname\n contains non-alphanumeric characters\n\n\nage\n is a negative number \n-42\n\n\nemail\n is not correctly formatted \ntest@@vapor.codes\n\n\n\n\nLuckily the Validation package can help.\n\n\nValidatable\n\n\nLet's take a look at how the Validation package can help you validate incoming data. We'll start by conforming our \nUser\n model from the previous section to the \nValidatable\n protocol. \n\n\n\n\nNote\n\n\nThis assumes \nUser\n already conforms to \nReflectable\n (added by default when using one of Fluent's \nModel\n protocols). If not, you will need to add conformance to \nReflectable\n manually.\n\n\n\n\nextension\n \nUser\n:\n \nValidatable\n \n{\n\n     \n/// See `Validatable`.\n\n     \nstatic\n \nfunc\n \nvalidations\n()\n \n-\n \nValidations\nUser\n \n{\n\n         \n// define validations\n\n     \n}\n\n\n}\n\n\n\nlet\n \nuser\n \n=\n \nUser\n(...)\n\n\n// since User conforms to Validatable, we get a new method validate()\n\n\n// that throws an error if any validations fail\n\n\ntry\n \nuser\n.\nvalidate\n()\n \n\n\n\n\n\nThis is the basic structure of \nValidatable\n conformance. Let's take a look at how we can implement the static \nvalidations()\n method.\n\n\nValidations\n\n\nFirst let's start by verifying that the name is at least 3 characters long.\n\n\nextension\n \nUser\n:\n \nValidatable\n \n{\n\n    \n/// See `Validatable`.\n\n    \nstatic\n \nfunc\n \nvalidations\n()\n \nthrows\n \n-\n \nValidations\nUser\n \n{\n\n        \nvar\n \nvalidations\n \n=\n \nValidations\n(\nUser\n.\nself\n)\n\n        \ntry\n \nvalidations\n.\nadd\n(\n\\\n.\nname\n,\n \n.\ncount\n(\n3.\n..))\n\n        \nreturn\n \nvalidations\n\n    \n}\n\n\n}\n\n\n\n\n\n\nThe \ncount(...)\n validation accepts Swift \nRange\n notation and will validate that a collection's count is within that range. By only placing a value on the left side of \n...\n, we only set a minimum range.\n\n\nTake a look at all of the available validators \nhere\n.\n\n\nOperators\n\n\nValidating that the name is three or more characters is great, but we also want to make sure that the name is alphanumeric characters only. We can do this by combining multiple validators using \n.\n\n\ntry\n \nvalidations\n.\nadd\n(\n\\\n.\nname\n,\n \n.\ncount\n(\n3.\n..)\n \n \n.\nalphanumeric\n)\n\n\n\n\n\n\nNow our name will only be considered valid if it is three or more characters \nand\n alphanumeric. Take a look at all of the available operators \nhere\n.\n\n\nNil\n\n\nYou may want to run validations on optionals only if a value is present. The \n and \n||\n operators have special overloads that help you do this. \n\n\ntry\n \nvalidations\n.\nadd\n(\n\\\n.\nemail\n,\n \n.\nemail\n \n||\n \n.\nnil\n)\n\n\n\n\n\n\nThe \nnil\n validator checks if a \nT?\n optional value is \nnil\n.\n\n\nThe \nemail\n validator checks if a \nString\n is a valid email address. However, the property on our \nUser\n is a \nString?\n. This means the email validator cannot be used directly with the property.\n\n\nWe can combine these two operators using \n||\n to express the validation we want: validate the email is correctly formatted if it is not nil.\n\n\nValidate\n\n\nLet's finish up the rest of our validations using our new knowledge.\n\n\nextension\n \nUser\n:\n \nValidatable\n \n{\n\n    \n/// See `Validatable`.\n\n    \nstatic\n \nfunc\n \nvalidations\n()\n \nthrows\n \n-\n \nValidations\nUser\n \n{\n\n        \nvar\n \nvalidations\n \n=\n \nValidations\n(\nUser\n.\nself\n)\n\n        \ntry\n \nvalidations\n.\nadd\n(\n\\\n.\nname\n,\n \n.\nalphanumeric\n \n \n.\ncount\n(\n3.\n..))\n\n        \ntry\n \nvalidations\n.\nadd\n(\n\\\n.\nage\n,\n \n.\nrange\n(\n18.\n..))\n\n        \ntry\n \nvalidations\n.\nadd\n(\n\\\n.\nemail\n,\n \n.\nemail\n \n||\n \n.\nnil\n)\n\n        \nreturn\n \nvalidations\n\n    \n}\n\n\n}\n\n\n\n\n\n\nNow let's try out validating our model.\n\n\nrouter\n.\npost\n(\nUser\n.\nself\n,\n \nat\n:\n \nusers\n)\n \n{\n \nreq\n,\n \nuser\n \n-\n \nUser\n \nin\n\n    \ntry\n \nuser\n.\nvalidate\n()\n\n    \nreturn\n \nuser\n\n\n}\n\n\n\n\n\n\nWhen you query that route, you should see that errors are thrown if the data does not meet your validations. If the data is correct, your user model is returned successfully.\n\n\nCongratulations on setting up your first \nValidatable\n model! Check out the \nAPI docs\n for more information and code samples.", 
            "title": "Overview"
        }, 
        {
            "location": "/validation/overview/#validation-overview", 
            "text": "Validation is a framework for validating data sent to your application. It can help validate things like names, emails and more. It is also extensible, allowing you to easily create custom validators.", 
            "title": "Validation Overview"
        }, 
        {
            "location": "/validation/overview/#swift-codable", 
            "text": "Swift's strong type system and  Codable  take care of most of the basic validation that web apps need to do.   struct   User :   Codable   { \n     var   id :   UUID ? \n     var   name :   String \n     var   age :   Int \n     var   email :   String ?  }   For example, when you decode the above  User  model, Swift will automatically ensure the following:   id  is a valid  UUID  or is  nil .  name  is a valid  String  and is  not   nil .  age  is a valid  Int  and is  not   nil .  email  is a valid  String  or is  nil .   This is a great first step, but there is still room for improvement here. Here are some examples of things Swift and  Codable  would not mind, but are not ideal:   name  is empty string  \"\"  name  contains non-alphanumeric characters  age  is a negative number  -42  email  is not correctly formatted  test@@vapor.codes   Luckily the Validation package can help.", 
            "title": "Swift &amp; Codable"
        }, 
        {
            "location": "/validation/overview/#validatable", 
            "text": "Let's take a look at how the Validation package can help you validate incoming data. We'll start by conforming our  User  model from the previous section to the  Validatable  protocol.    Note  This assumes  User  already conforms to  Reflectable  (added by default when using one of Fluent's  Model  protocols). If not, you will need to add conformance to  Reflectable  manually.   extension   User :   Validatable   { \n      /// See `Validatable`. \n      static   func   validations ()   -   Validations User   { \n          // define validations \n      }  }  let   user   =   User (...)  // since User conforms to Validatable, we get a new method validate()  // that throws an error if any validations fail  try   user . validate ()    This is the basic structure of  Validatable  conformance. Let's take a look at how we can implement the static  validations()  method.", 
            "title": "Validatable"
        }, 
        {
            "location": "/validation/overview/#validations", 
            "text": "First let's start by verifying that the name is at least 3 characters long.  extension   User :   Validatable   { \n     /// See `Validatable`. \n     static   func   validations ()   throws   -   Validations User   { \n         var   validations   =   Validations ( User . self ) \n         try   validations . add ( \\ . name ,   . count ( 3. ..)) \n         return   validations \n     }  }   The  count(...)  validation accepts Swift  Range  notation and will validate that a collection's count is within that range. By only placing a value on the left side of  ... , we only set a minimum range.  Take a look at all of the available validators  here .", 
            "title": "Validations"
        }, 
        {
            "location": "/validation/overview/#operators", 
            "text": "Validating that the name is three or more characters is great, but we also want to make sure that the name is alphanumeric characters only. We can do this by combining multiple validators using  .  try   validations . add ( \\ . name ,   . count ( 3. ..)     . alphanumeric )   Now our name will only be considered valid if it is three or more characters  and  alphanumeric. Take a look at all of the available operators  here .", 
            "title": "Operators"
        }, 
        {
            "location": "/validation/overview/#nil", 
            "text": "You may want to run validations on optionals only if a value is present. The   and  ||  operators have special overloads that help you do this.   try   validations . add ( \\ . email ,   . email   ||   . nil )   The  nil  validator checks if a  T?  optional value is  nil .  The  email  validator checks if a  String  is a valid email address. However, the property on our  User  is a  String? . This means the email validator cannot be used directly with the property.  We can combine these two operators using  ||  to express the validation we want: validate the email is correctly formatted if it is not nil.", 
            "title": "Nil"
        }, 
        {
            "location": "/validation/overview/#validate", 
            "text": "Let's finish up the rest of our validations using our new knowledge.  extension   User :   Validatable   { \n     /// See `Validatable`. \n     static   func   validations ()   throws   -   Validations User   { \n         var   validations   =   Validations ( User . self ) \n         try   validations . add ( \\ . name ,   . alphanumeric     . count ( 3. ..)) \n         try   validations . add ( \\ . age ,   . range ( 18. ..)) \n         try   validations . add ( \\ . email ,   . email   ||   . nil ) \n         return   validations \n     }  }   Now let's try out validating our model.  router . post ( User . self ,   at :   users )   {   req ,   user   -   User   in \n     try   user . validate () \n     return   user  }   When you query that route, you should see that errors are thrown if the data does not meet your validations. If the data is correct, your user model is returned successfully.  Congratulations on setting up your first  Validatable  model! Check out the  API docs  for more information and code samples.", 
            "title": "Validate"
        }, 
        {
            "location": "/vapor/getting-started/", 
            "text": "Getting Started with Vapor\n\n\nCheck out the main \nGetting Started\n guide which covers Vapor specifically. This page is here mostly for consistency with the rest of the packages.\n\n\nMore in-depth information on the APIs included in Vapor, see the sub-sections to the left.\n\n\nPackage\n\n\nIf you don't want to use one of Vapor's templates to get started, you can always include the framework manually.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/vapor.git\n,\n \nfrom\n:\n \n3.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nVapor\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport Vapor\n to access the APIs.\n\n\nAPI Docs\n\n\nThe rest of this guide will give you an overview of what is available in the Vapor package. As always, feel free to visit the \nAPI docs\n for more in-depth information.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/vapor/getting-started/#getting-started-with-vapor", 
            "text": "Check out the main  Getting Started  guide which covers Vapor specifically. This page is here mostly for consistency with the rest of the packages.  More in-depth information on the APIs included in Vapor, see the sub-sections to the left.", 
            "title": "Getting Started with Vapor"
        }, 
        {
            "location": "/vapor/getting-started/#package", 
            "text": "If you don't want to use one of Vapor's templates to get started, you can always include the framework manually.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/vapor.git ,   from :   3.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ Vapor ,   ...   ]) \n     ]  )   Use  import Vapor  to access the APIs.", 
            "title": "Package"
        }, 
        {
            "location": "/vapor/getting-started/#api-docs", 
            "text": "The rest of this guide will give you an overview of what is available in the Vapor package. As always, feel free to visit the  API docs  for more in-depth information.", 
            "title": "API Docs"
        }, 
        {
            "location": "/vapor/client/", 
            "text": "Using Client\n\n\nClient\n is a convenience wrapper around the lower level \nHTTP \n Client\n. It automatically parses things like hostname and port from URIs and helps you encode and decode \nContent\n.\n\n\nlet\n \nres\n \n=\n \ntry\n \nreq\n.\nclient\n().\nget\n(\nhttp://vapor.codes\n)\n\n\nprint\n(\nres\n)\n \n// Future\nResponse\n\n\n\n\n\n\nContainer\n\n\nThe first thing you will need is a service \nContainer\n to create your client.\n\n\nIf you are making this external API request as the result of an incoming request to your server, you should use the \nRequest\n container to create a client.  This is most often the case. \n\n\nIf you need a client during boot, use the \nApplication\n or if you are in a \nCommand\n use the command context's container.\n\n\nOnce you have a \nContainer\n, use the \nclient()\n method to create a \nClient\n.\n\n\n// Creates a generic Client\n\n\nlet\n \nclient\n \n=\n \ntry\n \ncontainer\n.\nclient\n()\n\n\n\n\n\n\nSend\n\n\nOnce you have a \nClient\n, you can use the \nsend(...)\n method to send a \nRequest\n. Note that the request URI must include a scheme and hostname.\n\n\nlet\n \nreq\n:\n \nRequest\n \n...\n\n\nlet\n \nres\n \n=\n \ntry\n \nclient\n.\nsend\n(\nreq\n)\n\n\nprint\n(\nres\n)\n \n// Future\nResponse\n\n\n\n\n\n\nYou can also use the convenience methods like \nget(...)\n, \npost(...)\n, etc.\n\n\nlet\n \nuser\n:\n \nUser\n \n...\n\n\nlet\n \nres\n \n=\n \ntry\n \nclient\n.\npost\n(\nhttp://api.vapor.codes/users\n)\n \n{\n \npost\n \nin\n\n    \ntry\n \npost\n.\ncontent\n.\nencode\n(\nuser\n)\n\n\n}\n\n\nprint\n(\nres\n)\n \n// Future\nResponse\n\n\n\n\n\n\nSee \nContent\n for more information on encoding and decoding content to messages.", 
            "title": "Client"
        }, 
        {
            "location": "/vapor/client/#using-client", 
            "text": "Client  is a convenience wrapper around the lower level  HTTP   Client . It automatically parses things like hostname and port from URIs and helps you encode and decode  Content .  let   res   =   try   req . client (). get ( http://vapor.codes )  print ( res )   // Future Response", 
            "title": "Using Client"
        }, 
        {
            "location": "/vapor/client/#container", 
            "text": "The first thing you will need is a service  Container  to create your client.  If you are making this external API request as the result of an incoming request to your server, you should use the  Request  container to create a client.  This is most often the case.   If you need a client during boot, use the  Application  or if you are in a  Command  use the command context's container.  Once you have a  Container , use the  client()  method to create a  Client .  // Creates a generic Client  let   client   =   try   container . client ()", 
            "title": "Container"
        }, 
        {
            "location": "/vapor/client/#send", 
            "text": "Once you have a  Client , you can use the  send(...)  method to send a  Request . Note that the request URI must include a scheme and hostname.  let   req :   Request   ...  let   res   =   try   client . send ( req )  print ( res )   // Future Response   You can also use the convenience methods like  get(...) ,  post(...) , etc.  let   user :   User   ...  let   res   =   try   client . post ( http://api.vapor.codes/users )   {   post   in \n     try   post . content . encode ( user )  }  print ( res )   // Future Response   See  Content  for more information on encoding and decoding content to messages.", 
            "title": "Send"
        }, 
        {
            "location": "/vapor/content/", 
            "text": "Using Content\n\n\nIn Vapor 3, all content types (JSON, protobuf, \nURLEncodedForm\n, \nMultipart\n, etc) are treated the same. All you need to parse and serialize content is a \nCodable\n class or struct.\n\n\nFor this introduction, we will use mostly JSON as an example. But keep in mind the API is the same for any supported content type.\n\n\nServer\n\n\nThis first section will go over decoding and encoding messages sent between your server and connected clients. See the \nclient\n section for encoding and decoding content in messages sent to external APIs.\n\n\nRequest\n\n\nLet's take a look at how you would parse the following HTTP request sent to your server.\n\n\nPOST\n \n/login\n \nHTTP\n/\n1.1\n\n\nContent-Type\n:\n \napplication/json\n\n\n\n{\n\n    \nemail\n:\n \nuser@vapor.codes\n,\n\n    \npassword\n:\n \ndon\nt look!\n\n\n}\n\n\n\n\n\n\nFirst, create a struct or class that represents the data you expect. \n\n\nimport\n \nVapor\n\n\n\nstruct\n \nLoginRequest\n:\n \nContent\n \n{\n\n    \nvar\n \nemail\n:\n \nString\n\n    \nvar\n \npassword\n:\n \nString\n\n\n}\n\n\n\n\n\n\nNotice the key names exactly match the keys in the request data. The expected data types also match. Next conform this struct or class to \nContent\n.\n\n\nDecode\n\n\nNow we are ready to decode that HTTP request. Every \nRequest\n has a \nContentContainer\n that we can use to decode content from the message's body.\n\n\nrouter\n.\npost\n(\nlogin\n)\n \n{\n \nreq\n \n-\n \nFuture\nHTTPStatus\n \nin\n\n    \nreturn\n \nreq\n.\ncontent\n.\ndecode\n(\nLoginRequest\n.\nself\n).\nmap\n \n{\n \nloginRequest\n \nin\n\n        \nprint\n(\nloginRequest\n.\nemail\n)\n \n// user@vapor.codes\n\n        \nprint\n(\nloginRequest\n.\npassword\n)\n \n// don\nt look!\n\n        \nreturn\n \nHTTPStatus\n.\nok\n\n    \n}\n\n\n}\n\n\n\n\n\n\nWe use \n.map(to:)\n here since \ndecode(...)\n returns a \nfuture\n. \n\n\n\n\nNote\n\n\nDecoding content from requests is asynchronous because HTTP allows bodies to be split into multiple parts using chunked transfer encoding. \n\n\n\n\nRouter\n\n\nTo help make decoding content from incoming requests easier, Vapor offers a few extensions on \nRouter\n to do this automatically.\n\n\nrouter\n.\npost\n(\nLoginRequest\n.\nself\n,\n \nat\n:\n \nlogin\n)\n \n{\n \nreq\n,\n \nloginRequest\n \nin\n\n    \nprint\n(\nloginRequest\n.\nemail\n)\n \n// user@vapor.codes\n\n    \nprint\n(\nloginRequest\n.\npassword\n)\n \n// don\nt look!\n\n    \nreturn\n \nHTTPStatus\n.\nok\n\n\n}\n\n\n\n\n\n\nDetect Type\n\n\nSince the HTTP request in this example declared JSON as its content type, Vapor knows to use a JSON decoder automatically. This same method would work just as well for the following request.\n\n\nPOST\n \n/login\n \nHTTP\n/\n1.1\n\n\nContent-Type\n:\n \napplication/x-www-form-urlencoded\n\n\nemail=user@vapor.codes\ndon\nt+look!\n\n\n\n\n\nAll HTTP requests must include a content type to be valid. Because of this, Vapor will automatically choose an appropriate decoder or error if it encounters an unknown media type.\n\n\n\n\nTip\n\n\nYou can \nconfigure\n the default encoders and decoders Vapor uses.\n\n\n\n\nCustom\n\n\nYou can always override Vapor's default decoder and pass in a custom one if you want.\n\n\nlet\n \nuser\n \n=\n \ntry\n \nreq\n.\ncontent\n.\ndecode\n(\nUser\n.\nself\n,\n \nusing\n:\n \nJSONDecoder\n())\n\n\nprint\n(\nuser\n)\n \n// Future\nUser\n\n\n\n\n\n\nResponse\n\n\nLet's take a look at how you would create the following HTTP response from your server.\n\n\nHTTP\n/\n1.1\n \n200\n \nOK\n\n\nContent-Type\n:\n \napplication/json\n\n\n\n{\n\n    \nname\n:\n \nVapor User\n,\n\n    \nemail\n:\n \nuser@vapor.codes\n\n\n}\n\n\n\n\n\n\nJust like decoding, first create a struct or class that represents the data that you are expecting.\n\n\nimport\n \nVapor\n\n\n\nstruct\n \nUser\n:\n \nContent\n \n{\n\n    \nvar\n \nname\n:\n \nString\n\n    \nvar\n \nemail\n:\n \nString\n\n\n}\n\n\n\n\n\n\nThen just conform this struct or class to \nContent\n. \n\n\nEncode\n\n\nNow we are ready to encode that HTTP response.\n\n\nrouter\n.\nget\n(\nuser\n)\n \n{\n \nreq\n \n-\n \nUser\n \nin\n\n    \nreturn\n \nUser\n(\nname\n:\n \nVapor User\n,\n \nemail\n:\n \nuser@vapor.codes\n)\n\n\n}\n\n\n\n\n\n\nThis will create a default \nResponse\n with \n200 OK\n status code and minimal headers. You can customize the response using a convenience \nencode(...)\n method.\n\n\nrouter\n.\nget\n(\nuser\n)\n \n{\n \nreq\n \n-\n \nFuture\nResponse\n \nin\n\n    \nreturn\n \nUser\n(\nname\n:\n \nVapor User\n,\n \nemail\n:\n \nuser@vapor.codes\n)\n\n        \n.\nencode\n(\nstatus\n:\n \n.\ncreated\n)\n\n\n}\n\n\n\n\n\n\nOverride Type\n\n\nContent will automatically encode as JSON by default. You can always override which content type is used\nusing the \nas:\n parameter.\n\n\ntry\n \nres\n.\ncontent\n.\nencode\n(\nuser\n,\n \nas\n:\n \n.\nurlEncodedForm\n)\n\n\n\n\n\n\nYou can also change the default media type for any class or struct.\n\n\nstruct\n \nUser\n:\n \nContent\n \n{\n\n    \n/// See `Content`.\n\n    \nstatic\n \nlet\n \ndefaultContentType\n:\n \nMediaType\n \n=\n \n.\nurlEncodedForm\n\n\n    \n...\n\n\n}\n\n\n\n\n\n\nClient\n\n\nEncoding content to HTTP requests sent by \nClient\ns is similar to encoding HTTP responses returned by your server. \n\n\nRequest\n\n\nLet's take a look at how we can encode the following request.\n\n\nPOST\n \n/login\n \nHTTP\n/\n1.1\n\n\nHost\n:\n \napi.vapor.codes\n\n\nContent-Type\n:\n \napplication/json\n\n\n\n{\n\n    \nemail\n:\n \nuser@vapor.codes\n,\n\n    \npassword\n:\n \ndon\nt look!\n\n\n}\n\n\n\n\n\n\nEncode\n\n\nFirst, create a struct or class that represents the data you expect.\n\n\nimport\n \nVapor\n\n\n\nstruct\n \nLoginRequest\n:\n \nContent\n \n{\n\n    \nvar\n \nemail\n:\n \nString\n\n    \nvar\n \npassword\n:\n \nString\n\n\n}\n\n\n\n\n\n\nNow we are ready to make our request. Let's assume we are making this request inside of a route closure, so we will use the \nincoming\n request as our container. \n\n\nlet\n \nloginRequest\n \n=\n \nLoginRequest\n(\nemail\n:\n \nuser@vapor.codes\n,\n \npassword\n:\n \ndon\nt look!\n)\n\n\nlet\n \nres\n \n=\n \ntry\n \nreq\n.\nclient\n().\npost\n(\nhttps://api.vapor.codes/login\n)\n \n{\n \nloginReq\n \nin\n\n    \n// encode the loginRequest before sending\n\n    \ntry\n \nloginReq\n.\ncontent\n.\nencode\n(\nloginRequest\n)\n\n\n}\n\n\nprint\n(\nres\n)\n \n// Future\nResponse\n\n\n\n\n\n\nResponse\n\n\nContinuing from our example in the encode section, let's see how we would decode content from the client's response.\n\n\nHTTP\n/\n1.1\n \n200\n \nOK\n\n\nContent-Type\n:\n \napplication/json\n\n\n\n{\n\n    \nname\n:\n \nVapor User\n,\n\n    \nemail\n:\n \nuser@vapor.codes\n\n\n}\n\n\n\n\n\n\nFirst of course we must create a struct or class to represent the data.\n\n\nimport\n \nVapor\n\n\n\nstruct\n \nUser\n:\n \nContent\n \n{\n\n    \nvar\n \nname\n:\n \nString\n\n    \nvar\n \nemail\n:\n \nString\n\n\n}\n\n\n\n\n\n\nDecode\n\n\nNow we are ready to decode the client response.\n\n\nlet\n \nres\n:\n \nFuture\nResponse\n \n// from the Client\n\n\n\nlet\n \nuser\n \n=\n \nres\n.\nflatMap\n \n{\n \ntry\n \n$0\n.\ncontent\n.\ndecode\n(\nUser\n.\nself\n)\n \n}\n\n\nprint\n(\nuser\n)\n \n// Future\nUser\n\n\n\n\n\n\nExample\n\n\nLet's now take a look at our complete \nClient\n request that both encodes and decodes content.\n\n\n// Create the LoginRequest data\n\n\nlet\n \nloginRequest\n \n=\n \nLoginRequest\n(\nemail\n:\n \nuser@vapor.codes\n,\n \npassword\n:\n \ndon\nt look!\n)\n\n\n// POST /login\n\n\nlet\n \nuser\n \n=\n \ntry\n \nreq\n.\nclient\n().\npost\n(\nhttps://api.vapor.codes/login\n)\n \n{\n \nloginReq\n \nin\n \n    \n// Encode Content before Request is sent\n\n    \nreturn\n \ntry\n \nloginReq\n.\ncontent\n.\nencode\n(\nloginRequest\n)\n \n\n}.\nflatMap\n \n{\n \nloginRes\n \nin\n\n    \n// Decode Content after Response is received\n\n    \nreturn\n \ntry\n \nloginRes\n.\ncontent\n.\ndecode\n(\nUser\n.\nself\n)\n \n\n}\n\n\nprint\n(\nuser\n)\n \n// Future\nUser\n\n\n\n\n\n\nQuery String\n\n\nURL-Encoded Form data can be encoded and decoded from an HTTP request's URI query string just like content. All you need is a class or struct that conforms to \nContent\n. In these examples, we will be using the following struct.\n\n\nstruct\n \nFlags\n:\n \nContent\n \n{\n\n     \nvar\n \nsearch\n:\n \nString\n?\n\n     \nvar\n \nisAdmin\n:\n \nBool\n?\n\n\n}\n\n\n\n\n\n\nDecode\n\n\nAll \nRequest\ns have a \nQueryContainer\n that you can use to decode the query string.\n\n\nlet\n \nflags\n \n=\n \ntry\n \nreq\n.\nquery\n.\ndecode\n(\nFlags\n.\nself\n)\n\n\nprint\n(\nflags\n)\n \n// Flags\n\n\n\n\n\n\nEncode\n\n\nYou can also encode content. This is useful for encoding query strings when using \nClient\n.\n\n\nlet\n \nflags\n:\n \nFlags\n \n...\n\n\ntry\n \nreq\n.\nquery\n.\nencode\n(\nflags\n)\n\n\n\n\n\n\nDynamic Properties\n\n\nOne of the most frequently asked questions regarding \nContent\n is:\n\n\n\n\nHow do I add a property to just this response?\n\n\n\n\nThe way Vapor 3 handles \nContent\n is based entirely on \nCodable\n. At no point (that is publically accessible) is your data in an arbitrary data structure like \n[String: Any]\n that you can mutate at will. Because of this, all data structures that your app accepts and returns \nmust\n be statically defined.\n\n\nLet's take a look at a common scenario to better understand this. Very often when you are creating a user, there are a couple different data formats required:\n\n\n\n\ncreate: password should be supplied twice to check values match\n\n\ninternal: you should store a hash not the plaintext password\n\n\npublic: when listing users, the password hash should not be included\n\n\n\n\nTo do this, you should create three types.\n\n\n// Data required to create a user\n\n\nstruct\n \nUserCreate\n:\n \nContent\n \n{\n\n    \nvar\n \nemail\n:\n \nString\n\n    \nvar\n \npassword\n:\n \nString\n\n    \nvar\n \npasswordCheck\n:\n \nString\n\n\n}\n\n\n\n// Our internal User representation\n\n\nstruct\n \nUser\n:\n \nModel\n \n{\n\n    \nvar\n \nid\n:\n \nInt\n?\n\n    \nvar\n \nemail\n:\n \nString\n\n    \nvar\n \npasswordHash\n:\n \nData\n\n\n}\n\n\n\n// Public user representation\n\n\nstruct\n \nPublicUser\n:\n \nContent\n \n{\n\n    \nvar\n \nid\n:\n \nInt\n\n    \nvar\n \nemail\n:\n \nString\n\n\n}\n\n\n\n// Create a router for POST /users\n\n\nrouter\n.\npost\n(\nUserCreate\n.\nself\n,\n \nat\n:\n \nusers\n)\n \n{\n \nreq\n,\n \nuserCreate\n \n-\n \nPublicUser\n \nin\n\n    \nguard\n \nuserCreate\n.\npassword\n \n==\n \npasswordCheck\n \nelse\n \n{\n \n/* some error */\n \n}\n\n    \nlet\n \nhasher\n \n=\n \ntry\n \nreq\n.\nmake\n(\n/* some hasher */\n)\n\n    \nlet\n \nuser\n \n=\n \ntry\n \nUser\n(\n\n        \nemail\n:\n \nuserCreate\n.\nemail\n,\n \n        \npasswordHash\n:\n \nhasher\n.\nhash\n(\nuserCreate\n.\npassword\n)\n\n    \n)\n\n    \n// save user\n\n    \nreturn\n \ntry\n \nPublicUser\n(\nid\n:\n \nuser\n.\nrequireID\n(),\n \nemail\n:\n \nuser\n.\nemail\n)\n\n\n}\n\n\n\n\n\n\nFor other methods such as \nPATCH\n and \nPUT\n, you may want to create additional types to supports the unique semantics.\n\n\nBenefits\n\n\nThis method may seem a bit verbose at first when compared to dynamic solutions, but it has a number of key advantages:\n\n\n\n\nStatically Typed\n: Very little validation is needed on top of what Swift and Codable do automatically.\n\n\nReadability\n: No need for Strings and optional chaining when working with Swift types.\n\n\nMaintainable\n: Large projects will appreciate having this information separated and clearly stated.\n\n\nShareable\n: Types defining what content your routes accept and return can be used to conform to specifications like OpenAPI or even be shared directly with clients written in Swift.\n\n\nPerformance\n: Working with native Swift types is much more performant than mutating \n[String: Any]\n dictionaries.\n\n\n\n\nJSON\n\n\nJSON is a very popular encoding format for APIs and the way in which dates, data, floats, etc are encoded is non-standard. Because of this, Vapor makes it easy to use custom \nJSONDecoder\ns when you interact with other APIs.\n\n\n// Conforms to Encodable\n\n\nlet\n \nuser\n:\n \nUser\n \n...\n \n\n// Encode JSON using custom date encoding strategy\n\n\ntry\n \nreq\n.\ncontent\n.\nencode\n(\njson\n:\n \nuser\n,\n \nusing\n:\n \n.\ncustom\n(\ndates\n:\n \n.\nmillisecondsSince1970\n))\n\n\n\n\n\n\nYou can also use this method for decoding.\n\n\n// Decode JSON using custom date encoding strategy\n\n\nlet\n \nuser\n \n=\n \ntry\n \nreq\n.\ncontent\n.\ndecode\n(\njson\n:\n \nUser\n.\nself\n,\n \nusing\n:\n \n.\ncustom\n(\ndates\n:\n \n.\nmillisecondsSince1970\n))\n\n\n\n\n\n\nIf you would like to set a custom JSON encoder or decoder globally, you can do so using \nconfiguration\n.\n\n\nConfigure\n\n\nUse \nContentConfig\n to register custom encoder/decoders for your application. These custom coders will be used anywhere you do \ncontent.encode\n/\ncontent.decode\n.\n\n\n/// Create default content config\n\n\nvar\n \ncontentConfig\n \n=\n \nContentConfig\n.\ndefault\n()\n\n\n\n/// Create custom JSON encoder\n\n\nvar\n \njsonEncoder\n \n=\n \nJSONEncoder\n()\n\n\njsonEncoder\n.\ndateEncodingStrategy\n \n=\n \n.\nmillisecondsSince1970\n\n\n\n/// Register JSON encoder and content config\n\n\ncontentConfig\n.\nuse\n(\nencoder\n:\n \njsonEncoder\n,\n \nfor\n:\n \n.\njson\n)\n\n\nservices\n.\nregister\n(\ncontentConfig\n)", 
            "title": "Content"
        }, 
        {
            "location": "/vapor/content/#using-content", 
            "text": "In Vapor 3, all content types (JSON, protobuf,  URLEncodedForm ,  Multipart , etc) are treated the same. All you need to parse and serialize content is a  Codable  class or struct.  For this introduction, we will use mostly JSON as an example. But keep in mind the API is the same for any supported content type.", 
            "title": "Using Content"
        }, 
        {
            "location": "/vapor/content/#server", 
            "text": "This first section will go over decoding and encoding messages sent between your server and connected clients. See the  client  section for encoding and decoding content in messages sent to external APIs.", 
            "title": "Server"
        }, 
        {
            "location": "/vapor/content/#request", 
            "text": "Let's take a look at how you would parse the following HTTP request sent to your server.  POST   /login   HTTP / 1.1  Content-Type :   application/json  { \n     email :   user@vapor.codes , \n     password :   don t look!  }   First, create a struct or class that represents the data you expect.   import   Vapor  struct   LoginRequest :   Content   { \n     var   email :   String \n     var   password :   String  }   Notice the key names exactly match the keys in the request data. The expected data types also match. Next conform this struct or class to  Content .", 
            "title": "Request"
        }, 
        {
            "location": "/vapor/content/#decode", 
            "text": "Now we are ready to decode that HTTP request. Every  Request  has a  ContentContainer  that we can use to decode content from the message's body.  router . post ( login )   {   req   -   Future HTTPStatus   in \n     return   req . content . decode ( LoginRequest . self ). map   {   loginRequest   in \n         print ( loginRequest . email )   // user@vapor.codes \n         print ( loginRequest . password )   // don t look! \n         return   HTTPStatus . ok \n     }  }   We use  .map(to:)  here since  decode(...)  returns a  future .    Note  Decoding content from requests is asynchronous because HTTP allows bodies to be split into multiple parts using chunked transfer encoding.", 
            "title": "Decode"
        }, 
        {
            "location": "/vapor/content/#router", 
            "text": "To help make decoding content from incoming requests easier, Vapor offers a few extensions on  Router  to do this automatically.  router . post ( LoginRequest . self ,   at :   login )   {   req ,   loginRequest   in \n     print ( loginRequest . email )   // user@vapor.codes \n     print ( loginRequest . password )   // don t look! \n     return   HTTPStatus . ok  }", 
            "title": "Router"
        }, 
        {
            "location": "/vapor/content/#detect-type", 
            "text": "Since the HTTP request in this example declared JSON as its content type, Vapor knows to use a JSON decoder automatically. This same method would work just as well for the following request.  POST   /login   HTTP / 1.1  Content-Type :   application/x-www-form-urlencoded \n\nemail=user@vapor.codes don t+look!  All HTTP requests must include a content type to be valid. Because of this, Vapor will automatically choose an appropriate decoder or error if it encounters an unknown media type.   Tip  You can  configure  the default encoders and decoders Vapor uses.", 
            "title": "Detect Type"
        }, 
        {
            "location": "/vapor/content/#custom", 
            "text": "You can always override Vapor's default decoder and pass in a custom one if you want.  let   user   =   try   req . content . decode ( User . self ,   using :   JSONDecoder ())  print ( user )   // Future User", 
            "title": "Custom"
        }, 
        {
            "location": "/vapor/content/#response", 
            "text": "Let's take a look at how you would create the following HTTP response from your server.  HTTP / 1.1   200   OK  Content-Type :   application/json  { \n     name :   Vapor User , \n     email :   user@vapor.codes  }   Just like decoding, first create a struct or class that represents the data that you are expecting.  import   Vapor  struct   User :   Content   { \n     var   name :   String \n     var   email :   String  }   Then just conform this struct or class to  Content .", 
            "title": "Response"
        }, 
        {
            "location": "/vapor/content/#encode", 
            "text": "Now we are ready to encode that HTTP response.  router . get ( user )   {   req   -   User   in \n     return   User ( name :   Vapor User ,   email :   user@vapor.codes )  }   This will create a default  Response  with  200 OK  status code and minimal headers. You can customize the response using a convenience  encode(...)  method.  router . get ( user )   {   req   -   Future Response   in \n     return   User ( name :   Vapor User ,   email :   user@vapor.codes ) \n         . encode ( status :   . created )  }", 
            "title": "Encode"
        }, 
        {
            "location": "/vapor/content/#override-type", 
            "text": "Content will automatically encode as JSON by default. You can always override which content type is used\nusing the  as:  parameter.  try   res . content . encode ( user ,   as :   . urlEncodedForm )   You can also change the default media type for any class or struct.  struct   User :   Content   { \n     /// See `Content`. \n     static   let   defaultContentType :   MediaType   =   . urlEncodedForm \n\n     ...  }", 
            "title": "Override Type"
        }, 
        {
            "location": "/vapor/content/#client", 
            "text": "Encoding content to HTTP requests sent by  Client s is similar to encoding HTTP responses returned by your server.", 
            "title": "Client"
        }, 
        {
            "location": "/vapor/content/#request_1", 
            "text": "Let's take a look at how we can encode the following request.  POST   /login   HTTP / 1.1  Host :   api.vapor.codes  Content-Type :   application/json  { \n     email :   user@vapor.codes , \n     password :   don t look!  }", 
            "title": "Request"
        }, 
        {
            "location": "/vapor/content/#encode_1", 
            "text": "First, create a struct or class that represents the data you expect.  import   Vapor  struct   LoginRequest :   Content   { \n     var   email :   String \n     var   password :   String  }   Now we are ready to make our request. Let's assume we are making this request inside of a route closure, so we will use the  incoming  request as our container.   let   loginRequest   =   LoginRequest ( email :   user@vapor.codes ,   password :   don t look! )  let   res   =   try   req . client (). post ( https://api.vapor.codes/login )   {   loginReq   in \n     // encode the loginRequest before sending \n     try   loginReq . content . encode ( loginRequest )  }  print ( res )   // Future Response", 
            "title": "Encode"
        }, 
        {
            "location": "/vapor/content/#response_1", 
            "text": "Continuing from our example in the encode section, let's see how we would decode content from the client's response.  HTTP / 1.1   200   OK  Content-Type :   application/json  { \n     name :   Vapor User , \n     email :   user@vapor.codes  }   First of course we must create a struct or class to represent the data.  import   Vapor  struct   User :   Content   { \n     var   name :   String \n     var   email :   String  }", 
            "title": "Response"
        }, 
        {
            "location": "/vapor/content/#decode_1", 
            "text": "Now we are ready to decode the client response.  let   res :   Future Response   // from the Client  let   user   =   res . flatMap   {   try   $0 . content . decode ( User . self )   }  print ( user )   // Future User", 
            "title": "Decode"
        }, 
        {
            "location": "/vapor/content/#example", 
            "text": "Let's now take a look at our complete  Client  request that both encodes and decodes content.  // Create the LoginRequest data  let   loginRequest   =   LoginRequest ( email :   user@vapor.codes ,   password :   don t look! )  // POST /login  let   user   =   try   req . client (). post ( https://api.vapor.codes/login )   {   loginReq   in  \n     // Encode Content before Request is sent \n     return   try   loginReq . content . encode ( loginRequest )   }. flatMap   {   loginRes   in \n     // Decode Content after Response is received \n     return   try   loginRes . content . decode ( User . self )   }  print ( user )   // Future User", 
            "title": "Example"
        }, 
        {
            "location": "/vapor/content/#query-string", 
            "text": "URL-Encoded Form data can be encoded and decoded from an HTTP request's URI query string just like content. All you need is a class or struct that conforms to  Content . In these examples, we will be using the following struct.  struct   Flags :   Content   { \n      var   search :   String ? \n      var   isAdmin :   Bool ?  }", 
            "title": "Query String"
        }, 
        {
            "location": "/vapor/content/#decode_2", 
            "text": "All  Request s have a  QueryContainer  that you can use to decode the query string.  let   flags   =   try   req . query . decode ( Flags . self )  print ( flags )   // Flags", 
            "title": "Decode"
        }, 
        {
            "location": "/vapor/content/#encode_2", 
            "text": "You can also encode content. This is useful for encoding query strings when using  Client .  let   flags :   Flags   ...  try   req . query . encode ( flags )", 
            "title": "Encode"
        }, 
        {
            "location": "/vapor/content/#dynamic-properties", 
            "text": "One of the most frequently asked questions regarding  Content  is:   How do I add a property to just this response?   The way Vapor 3 handles  Content  is based entirely on  Codable . At no point (that is publically accessible) is your data in an arbitrary data structure like  [String: Any]  that you can mutate at will. Because of this, all data structures that your app accepts and returns  must  be statically defined.  Let's take a look at a common scenario to better understand this. Very often when you are creating a user, there are a couple different data formats required:   create: password should be supplied twice to check values match  internal: you should store a hash not the plaintext password  public: when listing users, the password hash should not be included   To do this, you should create three types.  // Data required to create a user  struct   UserCreate :   Content   { \n     var   email :   String \n     var   password :   String \n     var   passwordCheck :   String  }  // Our internal User representation  struct   User :   Model   { \n     var   id :   Int ? \n     var   email :   String \n     var   passwordHash :   Data  }  // Public user representation  struct   PublicUser :   Content   { \n     var   id :   Int \n     var   email :   String  }  // Create a router for POST /users  router . post ( UserCreate . self ,   at :   users )   {   req ,   userCreate   -   PublicUser   in \n     guard   userCreate . password   ==   passwordCheck   else   {   /* some error */   } \n     let   hasher   =   try   req . make ( /* some hasher */ ) \n     let   user   =   try   User ( \n         email :   userCreate . email ,  \n         passwordHash :   hasher . hash ( userCreate . password ) \n     ) \n     // save user \n     return   try   PublicUser ( id :   user . requireID (),   email :   user . email )  }   For other methods such as  PATCH  and  PUT , you may want to create additional types to supports the unique semantics.", 
            "title": "Dynamic Properties"
        }, 
        {
            "location": "/vapor/content/#benefits", 
            "text": "This method may seem a bit verbose at first when compared to dynamic solutions, but it has a number of key advantages:   Statically Typed : Very little validation is needed on top of what Swift and Codable do automatically.  Readability : No need for Strings and optional chaining when working with Swift types.  Maintainable : Large projects will appreciate having this information separated and clearly stated.  Shareable : Types defining what content your routes accept and return can be used to conform to specifications like OpenAPI or even be shared directly with clients written in Swift.  Performance : Working with native Swift types is much more performant than mutating  [String: Any]  dictionaries.", 
            "title": "Benefits"
        }, 
        {
            "location": "/vapor/content/#json", 
            "text": "JSON is a very popular encoding format for APIs and the way in which dates, data, floats, etc are encoded is non-standard. Because of this, Vapor makes it easy to use custom  JSONDecoder s when you interact with other APIs.  // Conforms to Encodable  let   user :   User   ...   // Encode JSON using custom date encoding strategy  try   req . content . encode ( json :   user ,   using :   . custom ( dates :   . millisecondsSince1970 ))   You can also use this method for decoding.  // Decode JSON using custom date encoding strategy  let   user   =   try   req . content . decode ( json :   User . self ,   using :   . custom ( dates :   . millisecondsSince1970 ))   If you would like to set a custom JSON encoder or decoder globally, you can do so using  configuration .", 
            "title": "JSON"
        }, 
        {
            "location": "/vapor/content/#configure", 
            "text": "Use  ContentConfig  to register custom encoder/decoders for your application. These custom coders will be used anywhere you do  content.encode / content.decode .  /// Create default content config  var   contentConfig   =   ContentConfig . default ()  /// Create custom JSON encoder  var   jsonEncoder   =   JSONEncoder ()  jsonEncoder . dateEncodingStrategy   =   . millisecondsSince1970  /// Register JSON encoder and content config  contentConfig . use ( encoder :   jsonEncoder ,   for :   . json )  services . register ( contentConfig )", 
            "title": "Configure"
        }, 
        {
            "location": "/vapor/sessions/", 
            "text": "Using Sessions\n\n\nThis guide will show you how to use sessions in Vapor to maintain state for a connected client.\n\n\nSessions work by creating unique identifiers for each new client and asking the client to supply this identifier with each request. When the next request is received, Vapor uses this unique identifier to restore the session data. This identifier could be transmitted in any format, but it is almost always done with cookies and that is how Vapor's sessions work. \n\n\nWhen a new client connects and session data is set, Vapor will return a \nSet-Cookie\n header. The client is then expected to re-supply the value with each request in a \nCookie\n header. All browsers do this automatically. If your ever decide to invalidate the session, Vapor will delete any related data and notify the client that their cookie is no longer valid.\n\n\nMiddleware\n\n\nThe first step to using sessions is enabling \nSessionsMiddleware\n. This can be done globally for the entire application or on a per-route basis.\n\n\nGlobally\n\n\nTo globally enable sessions, add the middleware to your \nMiddlewareConfig\n.\n\n\nvar\n \nmiddlewares\n \n=\n \nMiddlewareConfig\n.\ndefault\n()\n\n\nmiddlewares\n.\nuse\n(\nSessionsMiddleware\n.\nself\n)\n\n\nservices\n.\nregister\n(\nmiddlewares\n)\n\n\n\n\n\n\nThis is usually done in \nconfigure.swift\n.\n\n\nPer Route\n\n\nTo enable sessions for a group of routes, use the \ngrouped(...)\n methods on \nRouter\n.\n\n\n// create a grouped router at /sessions w/ sessions enabled\n\n\nlet\n \nsessions\n \n=\n \nrouter\n.\ngrouped\n(\nsessions\n).\ngrouped\n(\nSessionsMiddleware\n.\nself\n)\n\n\n\n// create a route at GET /sessions/foo\n\n\nsessions\n.\nget\n(\nfoo\n)\n \n{\n \nreq\n \nin\n\n    \n// use sessions\n\n\n}\n\n\n\n\n\n\nSessions\n\n\nWhen \nSessionsMiddleware\n boots it will attempt to make a \nSessions\n and a \nSessionsConfig\n. Vapor will use an in-memory session by default. You can override both of these services by registering them in \nconfigure.swift\n.\n\n\nYou can use Fluent databases (like MySQL, PostgreSQL, etc) or caches like Redis to store your sessions. See the respective guides for more information.\n\n\nSession\n\n\nOnce you have \nSessionsMiddleware\n enabled, you can use \nreq.session()\n to access the session. Here is a simple example that does simple CRUD operations on a \n\"name\"\n value in the session.\n\n\n// create a route at GET /sessions/get\n\n\nsessions\n.\nget\n(\nget\n)\n \n{\n \nreq\n \n-\n \nString\n \nin\n\n    \n// access \nname\n from session or return n/a\n\n    \nreturn\n \ntry\n \nreq\n.\nsession\n()[\nname\n]\n \n??\n \nn/a\n\n\n}\n\n\n\n// create a route at GET /sessions/set/:name\n\n\nsessions\n.\nget\n(\nset\n,\n \nString\n.\nparameter\n)\n \n{\n \nreq\n \n-\n \nString\n \nin\n\n    \n// get router param\n\n    \nlet\n \nname\n \n=\n \ntry\n \nreq\n.\nparameters\n.\nnext\n(\nString\n.\nself\n)\n\n\n    \n// set name to session at key \nname\n\n    \ntry\n \nreq\n.\nsession\n()[\nname\n]\n \n=\n \nname\n\n\n    \n// return the newly set name\n\n    \nreturn\n \nname\n\n\n}\n\n\n\n// create a route at GET /sessions/del\n\n\nsessions\n.\nget\n(\ndel\n)\n \n{\n \nreq\n \n-\n \nString\n \nin\n\n    \n// destroy the session\n\n    \ntry\n \nreq\n.\ndestroySession\n()\n\n\n    \n// signal success\n\n    \nreturn\n \ndone\n\n\n}\n\n\n\n\n\n\nThat's it, congratulations on getting sessions working!", 
            "title": "Sessions"
        }, 
        {
            "location": "/vapor/sessions/#using-sessions", 
            "text": "This guide will show you how to use sessions in Vapor to maintain state for a connected client.  Sessions work by creating unique identifiers for each new client and asking the client to supply this identifier with each request. When the next request is received, Vapor uses this unique identifier to restore the session data. This identifier could be transmitted in any format, but it is almost always done with cookies and that is how Vapor's sessions work.   When a new client connects and session data is set, Vapor will return a  Set-Cookie  header. The client is then expected to re-supply the value with each request in a  Cookie  header. All browsers do this automatically. If your ever decide to invalidate the session, Vapor will delete any related data and notify the client that their cookie is no longer valid.", 
            "title": "Using Sessions"
        }, 
        {
            "location": "/vapor/sessions/#middleware", 
            "text": "The first step to using sessions is enabling  SessionsMiddleware . This can be done globally for the entire application or on a per-route basis.", 
            "title": "Middleware"
        }, 
        {
            "location": "/vapor/sessions/#globally", 
            "text": "To globally enable sessions, add the middleware to your  MiddlewareConfig .  var   middlewares   =   MiddlewareConfig . default ()  middlewares . use ( SessionsMiddleware . self )  services . register ( middlewares )   This is usually done in  configure.swift .", 
            "title": "Globally"
        }, 
        {
            "location": "/vapor/sessions/#per-route", 
            "text": "To enable sessions for a group of routes, use the  grouped(...)  methods on  Router .  // create a grouped router at /sessions w/ sessions enabled  let   sessions   =   router . grouped ( sessions ). grouped ( SessionsMiddleware . self )  // create a route at GET /sessions/foo  sessions . get ( foo )   {   req   in \n     // use sessions  }", 
            "title": "Per Route"
        }, 
        {
            "location": "/vapor/sessions/#sessions", 
            "text": "When  SessionsMiddleware  boots it will attempt to make a  Sessions  and a  SessionsConfig . Vapor will use an in-memory session by default. You can override both of these services by registering them in  configure.swift .  You can use Fluent databases (like MySQL, PostgreSQL, etc) or caches like Redis to store your sessions. See the respective guides for more information.", 
            "title": "Sessions"
        }, 
        {
            "location": "/vapor/sessions/#session", 
            "text": "Once you have  SessionsMiddleware  enabled, you can use  req.session()  to access the session. Here is a simple example that does simple CRUD operations on a  \"name\"  value in the session.  // create a route at GET /sessions/get  sessions . get ( get )   {   req   -   String   in \n     // access  name  from session or return n/a \n     return   try   req . session ()[ name ]   ??   n/a  }  // create a route at GET /sessions/set/:name  sessions . get ( set ,   String . parameter )   {   req   -   String   in \n     // get router param \n     let   name   =   try   req . parameters . next ( String . self ) \n\n     // set name to session at key  name \n     try   req . session ()[ name ]   =   name \n\n     // return the newly set name \n     return   name  }  // create a route at GET /sessions/del  sessions . get ( del )   {   req   -   String   in \n     // destroy the session \n     try   req . destroySession () \n\n     // signal success \n     return   done  }   That's it, congratulations on getting sessions working!", 
            "title": "Session"
        }, 
        {
            "location": "/vapor/websocket/", 
            "text": "Using WebSockets\n\n\nVapor includes convenience methods for working with the lower level WebSocket \nclient\n and \nserver\n. \n\n\nServer\n\n\nVapor's WebSocket server includes the ability to route incoming requests just like its HTTP server. \n\n\nWhen Vapor's main HTTP \nServer\n boots it will attempt to create a \nWebSocketServer\n. If one is registered, it will be added as an HTTP upgrade handler to the server. \n\n\nSo to create a WebSocket server, all you need to do is register one in  \nconfigure.swift\n.\n\n\n// Create a new NIO websocket server\n\n\nlet\n \nwss\n \n=\n \nNIOWebSocketServer\n.\ndefault\n()\n\n\n\n// Add WebSocket upgrade support to GET /echo\n\n\nwss\n.\nget\n(\necho\n)\n \n{\n \nws\n,\n \nreq\n \nin\n\n    \n// Add a new on text callback\n\n    \nws\n.\nonText\n \n{\n \nws\n,\n \ntext\n \nin\n\n        \n// Simply echo any received text\n\n        \nws\n.\nsend\n(\ntext\n)\n\n    \n}\n\n\n}\n\n\n\n// Register our server\n\n\nservices\n.\nregister\n(\nwss\n,\n \nas\n:\n \nWebSocketServer\n.\nself\n)\n\n\n\n\n\n\nThat's it. Next time you boot your server, you will be able to perform a WebSocket upgrade at \nGET /echo\n.  You can test this using a simple command line tool called \nwsta\n available for macOS and Linux.\n\n\n$ wsta ws://localhost:8080/echo\nConnected to ws://localhost:8080/echo\nhello, world!\nhello, world!\n\n\n\n\n\nParameters\n\n\nLike Vapor's HTTP router, you can also use routing parameters with your WebSocket server.\n\n\n// Add WebSocket upgrade support to GET /chat/:name\n\n\nwss\n.\nget\n(\nchat\n,\n \nString\n.\nparameter\n)\n \n{\n \nws\n,\n \nreq\n \nin\n\n    \nlet\n \nname\n \n=\n \ntry\n \nreq\n.\nparameters\n.\nnext\n(\nString\n.\nself\n)\n\n    \nws\n.\nsend\n(\nWelcome, \n\\(\nname\n)\n!\n)\n\n\n    \n// ...\n\n\n}\n\n\n\n\n\n\nNow let's test this new route:\n\n\n$ wsta ws://localhost:8080/chat/Vapor\nConnected to ws://localhost:8080/chat/Vapor\nWelcome, Vapor!\n\n\n\n\n\nClient\n\n\nVapor also supports connecting to WebSocket servers as a client. The easiest way to connect to a WebSocket server is through the \nwebSocket(...)\n method on \nClient\n.\n\n\nFor this example, we will assume our application connects to a WebSocket server in \nboot.swift\n\n\n// connect to echo.websocket.org\n\n\nlet\n \ndone\n \n=\n \ntry\n \napp\n.\nclient\n().\nwebSocket\n(\nws://echo.websocket.org\n).\nflatMap\n \n{\n \nws\n \n-\n \nFuture\nVoid\n \nin\n\n    \n// setup an on text callback that will print the echo\n\n    \nws\n.\nonText\n \n{\n \nws\n,\n \ntext\n \nin\n\n        \nprint\n(\nrec: \n\\(\ntext\n)\n)\n\n        \n// close the websocket connection after we recv the echo\n\n        \nws\n.\nclose\n()\n\n    \n}\n\n\n    \n// when the websocket first connects, send message\n\n    \nws\n.\nsend\n(\nhello, world!\n)\n\n\n    \n// return a future that will complete when the websocket closes\n\n    \nreturn\n \nws\n.\nonClose\n\n\n}\n\n\n\nprint\n(\ndone\n)\n \n// Future\nVoid\n\n\n\n// wait for the websocket to close\n\n\ntry\n \ndone\n.\nwait\n()", 
            "title": "WebSocket"
        }, 
        {
            "location": "/vapor/websocket/#using-websockets", 
            "text": "Vapor includes convenience methods for working with the lower level WebSocket  client  and  server .", 
            "title": "Using WebSockets"
        }, 
        {
            "location": "/vapor/websocket/#server", 
            "text": "Vapor's WebSocket server includes the ability to route incoming requests just like its HTTP server.   When Vapor's main HTTP  Server  boots it will attempt to create a  WebSocketServer . If one is registered, it will be added as an HTTP upgrade handler to the server.   So to create a WebSocket server, all you need to do is register one in   configure.swift .  // Create a new NIO websocket server  let   wss   =   NIOWebSocketServer . default ()  // Add WebSocket upgrade support to GET /echo  wss . get ( echo )   {   ws ,   req   in \n     // Add a new on text callback \n     ws . onText   {   ws ,   text   in \n         // Simply echo any received text \n         ws . send ( text ) \n     }  }  // Register our server  services . register ( wss ,   as :   WebSocketServer . self )   That's it. Next time you boot your server, you will be able to perform a WebSocket upgrade at  GET /echo .  You can test this using a simple command line tool called  wsta  available for macOS and Linux.  $ wsta ws://localhost:8080/echo\nConnected to ws://localhost:8080/echo\nhello, world!\nhello, world!", 
            "title": "Server"
        }, 
        {
            "location": "/vapor/websocket/#parameters", 
            "text": "Like Vapor's HTTP router, you can also use routing parameters with your WebSocket server.  // Add WebSocket upgrade support to GET /chat/:name  wss . get ( chat ,   String . parameter )   {   ws ,   req   in \n     let   name   =   try   req . parameters . next ( String . self ) \n     ws . send ( Welcome,  \\( name ) ! ) \n\n     // ...  }   Now let's test this new route:  $ wsta ws://localhost:8080/chat/Vapor\nConnected to ws://localhost:8080/chat/Vapor\nWelcome, Vapor!", 
            "title": "Parameters"
        }, 
        {
            "location": "/vapor/websocket/#client", 
            "text": "Vapor also supports connecting to WebSocket servers as a client. The easiest way to connect to a WebSocket server is through the  webSocket(...)  method on  Client .  For this example, we will assume our application connects to a WebSocket server in  boot.swift  // connect to echo.websocket.org  let   done   =   try   app . client (). webSocket ( ws://echo.websocket.org ). flatMap   {   ws   -   Future Void   in \n     // setup an on text callback that will print the echo \n     ws . onText   {   ws ,   text   in \n         print ( rec:  \\( text ) ) \n         // close the websocket connection after we recv the echo \n         ws . close () \n     } \n\n     // when the websocket first connects, send message \n     ws . send ( hello, world! ) \n\n     // return a future that will complete when the websocket closes \n     return   ws . onClose  }  print ( done )   // Future Void  // wait for the websocket to close  try   done . wait ()", 
            "title": "Client"
        }, 
        {
            "location": "/websocket/getting-started/", 
            "text": "Getting Started with WebSocket\n\n\nWebSocket (\nvapor/websocket\n) is a non-blocking, event-driven WebSocket library built on SwiftNIO. It makes working with SwiftNIO's WebSocket handlers easy and provides integration with \nHTTP\n clients and servers. Creating a WebSocket echo server takes just a few lines of code.\n\n\n\n\nTip\n\n\nIf you use Vapor, most of WebSocket's APIs will be wrapped by more convenient methods. \n\n\n\n\nVapor\n\n\nThis package is included with Vapor and exported by default. You will have access to all \nWebSocket\n APIs when you import \nVapor\n.\n\n\nimport\n \nVapor\n\n\n\n\n\n\nStandalone\n\n\nThe WebSocket package is lightweight, pure Swift, and only depends on SwiftNIO. This means it can be used as a WebSocket framework any Swift project\u2014even one not using Vapor.\n\n\nTo include it in your package, add the following to your \nPackage.swift\n file.\n\n\n// swift-tools-version:4.0\n\n\nimport\n \nPackageDescription\n\n\n\nlet\n \npackage\n \n=\n \nPackage\n(\n\n    \nname\n:\n \nProject\n,\n\n    \ndependencies\n:\n \n[\n\n        \n...\n\n        \n.\npackage\n(\nurl\n:\n \nhttps://github.com/vapor/websocket.git\n,\n \nfrom\n:\n \n1.0.0\n),\n\n    \n],\n\n    \ntargets\n:\n \n[\n\n      \n.\ntarget\n(\nname\n:\n \nProject\n,\n \ndependencies\n:\n \n[\nWebSocket\n,\n \n...\n \n])\n\n    \n]\n\n\n)\n\n\n\n\n\n\nUse \nimport WebSocket\n to access the APIs.\n\n\nThe rest of this guide will give you an overview of what is available in the WebSocket package. As always, feel free to visit the \nAPI docs\n for more in-depth information.", 
            "title": "Getting Started"
        }, 
        {
            "location": "/websocket/getting-started/#getting-started-with-websocket", 
            "text": "WebSocket ( vapor/websocket ) is a non-blocking, event-driven WebSocket library built on SwiftNIO. It makes working with SwiftNIO's WebSocket handlers easy and provides integration with  HTTP  clients and servers. Creating a WebSocket echo server takes just a few lines of code.   Tip  If you use Vapor, most of WebSocket's APIs will be wrapped by more convenient methods.", 
            "title": "Getting Started with WebSocket"
        }, 
        {
            "location": "/websocket/getting-started/#vapor", 
            "text": "This package is included with Vapor and exported by default. You will have access to all  WebSocket  APIs when you import  Vapor .  import   Vapor", 
            "title": "Vapor"
        }, 
        {
            "location": "/websocket/getting-started/#standalone", 
            "text": "The WebSocket package is lightweight, pure Swift, and only depends on SwiftNIO. This means it can be used as a WebSocket framework any Swift project\u2014even one not using Vapor.  To include it in your package, add the following to your  Package.swift  file.  // swift-tools-version:4.0  import   PackageDescription  let   package   =   Package ( \n     name :   Project , \n     dependencies :   [ \n         ... \n         . package ( url :   https://github.com/vapor/websocket.git ,   from :   1.0.0 ), \n     ], \n     targets :   [ \n       . target ( name :   Project ,   dependencies :   [ WebSocket ,   ...   ]) \n     ]  )   Use  import WebSocket  to access the APIs.  The rest of this guide will give you an overview of what is available in the WebSocket package. As always, feel free to visit the  API docs  for more in-depth information.", 
            "title": "Standalone"
        }, 
        {
            "location": "/websocket/overview/", 
            "text": "Using WebSockets\n\n\nUnlike HTTP, WebSockets allow you to communicate between client and server in an open, interactive way. You can send messages (called frames) in either text or binary format. Both the client and the server can send as many messages as they want at a time, without having to wait for responses.\n\n\nAlthough WebSocket is its own protocol, it still uses HTTP to get setup. Every WebSocket connection will start with an HTTP request with special headers followed by an HTTP response with status \n101 Switching Protocols\n. After this initial handshake, the connection is a WebSocket connection.\n\n\nWebSocket\n\n\nThe \nWebSocket\n class represents a connected WebSocket client. You can use this to set callbacks for receiving data and to send data.\n\n\nlet\n \nws\n:\n \nWebSocket\n \n=\n \n...\n\n\n// Send an initial message to this WebSocket\n\n\nws\n.\nsend\n(\nHello!\n)\n\n\n\n// Set a new callback for receiving text formatted data\n\n\nws\n.\nonText\n \n{\n \nws\n,\n \nstring\n \nin\n\n    \n// Echo the text back, reversed.\n\n    \nws\n.\nsend\n(\nstring\n.\nreversed\n())\n\n\n}\n\n\n\n\n\n\n\n\nTip\n\n\nAll callbacks will receive a reference to the \nWebSocket\n. Use these if you need to send data to avoid creating a reference cycle.\n\n\n\n\nThe \nWebSocket\n has an \nonClose\n future that will be completed when the connection closes. You can use \nclose()\n to close the connection yourself.\n\n\nServer\n\n\nWebSocket servers connect to one or more WebSocket clients at a time. As mentioned previously, WebSocket connections must start via an HTTP request and response handshake. Because of this, WebSocket servers are built on top of \nHTTP servers\n using the HTTP upgrade mechanism.\n\n\n// First, create an HTTPProtocolUpgrader\n\n\nlet\n \nws\n \n=\n \nHTTPServer\n.\nwebSocketUpgrader\n(\nshouldUpgrade\n:\n \n{\n \nreq\n \nin\n\n    \n// Returning nil in this closure will reject upgrade\n\n    \nif\n \nreq\n.\nurl\n.\npath\n \n==\n \n/deny\n \n{\n \nreturn\n \nnil\n \n}\n\n    \n// Return any additional headers you like, or just empty\n\n    \nreturn\n \n[:]\n\n\n},\n \nonUpgrade\n:\n \n{\n \nws\n,\n \nreq\n \nin\n\n    \n// This closure will be called with each new WebSocket client\n\n    \nws\n.\nsend\n(\nConnected\n)\n\n    \nws\n.\nonText\n \n{\n \nws\n,\n \nstring\n \nin\n\n        \nws\n.\nsend\n(\nstring\n.\nreversed\n())\n\n    \n}\n\n\n})\n\n\n\n// Next, create your server, adding the WebSocket upgrader\n\n\nlet\n \nserver\n \n=\n \ntry\n \nHTTPServer\n.\nstart\n(\n\n    \n...\n\n    \nupgraders\n:\n \n[\nws\n],\n\n    \n...\n\n\n).\nwait\n()\n\n\n// Run the server.\n\n\ntry\n \nserver\n.\nonClose\n.\nwait\n()\n\n\n\n\n\n\n\n\nSeealso\n\n\nVisit \nHTTP \u2192 Server\n for more information on setting up an HTTP server.\n\n\n\n\nThe WebSocket protocol upgrader consists of two callbacks. \n\n\nThe first callback \nshouldUpgrade\n receives the incoming HTTP request that is requesting upgrade. This callback decides whether or not to complete the upgrade based on the contents of the request. If \nnil\n is returned in this closure, the upgrade will be rejected.\n\n\nThe second callback \nonUpgrade\n is called each time a new WebSocket client connects. This is where you configure your callbacks and send any initial data.\n\n\n\n\nWarning\n\n\nThe upgrade closures may be called on any event loop. Be careful to avoid race conditions if you must access external variables.\n\n\n\n\nClient\n\n\nYou can also use the WebSocket package to connect \nto\n a WebSocket server. Just like the WebSocket server used an HTTP server, the WebSocket client uses HTTP client.\n\n\n// Create a new WebSocket connected to echo.websocket.org\n\n\nlet\n \nws\n \n=\n \ntry\n \nHTTPClient\n.\nwebSocket\n(\nhostname\n:\n \necho.websocket.org\n,\n \non\n:\n \n...).\nwait\n()\n\n\n\n// Set a new callback for receiving text formatted data.\n\n\nws\n.\nonText\n \n{\n \nws\n,\n \ntext\n \nin\n\n    \nprint\n(\nServer echo: \n\\(\ntext\n)\n)\n\n\n}\n\n\n\n// Send a message.\n\n\nws\n.\nsend\n(\nHello, world!\n)\n\n\n\n// Wait for the Websocket to closre.\n\n\ntry\n \nws\n.\nonClose\n.\nwait\n()\n\n\n\n\n\n\n\n\nSeealso\n\n\nVisit \nHTTP \u2192 Client\n for more information on setting up an HTTP client.\n\n\n\n\nAPI Docs\n\n\nCheck out the \nAPI docs\n for more in-depth information about all of the methods.", 
            "title": "Overview"
        }, 
        {
            "location": "/websocket/overview/#using-websockets", 
            "text": "Unlike HTTP, WebSockets allow you to communicate between client and server in an open, interactive way. You can send messages (called frames) in either text or binary format. Both the client and the server can send as many messages as they want at a time, without having to wait for responses.  Although WebSocket is its own protocol, it still uses HTTP to get setup. Every WebSocket connection will start with an HTTP request with special headers followed by an HTTP response with status  101 Switching Protocols . After this initial handshake, the connection is a WebSocket connection.", 
            "title": "Using WebSockets"
        }, 
        {
            "location": "/websocket/overview/#websocket", 
            "text": "The  WebSocket  class represents a connected WebSocket client. You can use this to set callbacks for receiving data and to send data.  let   ws :   WebSocket   =   ...  // Send an initial message to this WebSocket  ws . send ( Hello! )  // Set a new callback for receiving text formatted data  ws . onText   {   ws ,   string   in \n     // Echo the text back, reversed. \n     ws . send ( string . reversed ())  }    Tip  All callbacks will receive a reference to the  WebSocket . Use these if you need to send data to avoid creating a reference cycle.   The  WebSocket  has an  onClose  future that will be completed when the connection closes. You can use  close()  to close the connection yourself.", 
            "title": "WebSocket"
        }, 
        {
            "location": "/websocket/overview/#server", 
            "text": "WebSocket servers connect to one or more WebSocket clients at a time. As mentioned previously, WebSocket connections must start via an HTTP request and response handshake. Because of this, WebSocket servers are built on top of  HTTP servers  using the HTTP upgrade mechanism.  // First, create an HTTPProtocolUpgrader  let   ws   =   HTTPServer . webSocketUpgrader ( shouldUpgrade :   {   req   in \n     // Returning nil in this closure will reject upgrade \n     if   req . url . path   ==   /deny   {   return   nil   } \n     // Return any additional headers you like, or just empty \n     return   [:]  },   onUpgrade :   {   ws ,   req   in \n     // This closure will be called with each new WebSocket client \n     ws . send ( Connected ) \n     ws . onText   {   ws ,   string   in \n         ws . send ( string . reversed ()) \n     }  })  // Next, create your server, adding the WebSocket upgrader  let   server   =   try   HTTPServer . start ( \n     ... \n     upgraders :   [ ws ], \n     ...  ). wait ()  // Run the server.  try   server . onClose . wait ()    Seealso  Visit  HTTP \u2192 Server  for more information on setting up an HTTP server.   The WebSocket protocol upgrader consists of two callbacks.   The first callback  shouldUpgrade  receives the incoming HTTP request that is requesting upgrade. This callback decides whether or not to complete the upgrade based on the contents of the request. If  nil  is returned in this closure, the upgrade will be rejected.  The second callback  onUpgrade  is called each time a new WebSocket client connects. This is where you configure your callbacks and send any initial data.   Warning  The upgrade closures may be called on any event loop. Be careful to avoid race conditions if you must access external variables.", 
            "title": "Server"
        }, 
        {
            "location": "/websocket/overview/#client", 
            "text": "You can also use the WebSocket package to connect  to  a WebSocket server. Just like the WebSocket server used an HTTP server, the WebSocket client uses HTTP client.  // Create a new WebSocket connected to echo.websocket.org  let   ws   =   try   HTTPClient . webSocket ( hostname :   echo.websocket.org ,   on :   ...). wait ()  // Set a new callback for receiving text formatted data.  ws . onText   {   ws ,   text   in \n     print ( Server echo:  \\( text ) )  }  // Send a message.  ws . send ( Hello, world! )  // Wait for the Websocket to closre.  try   ws . onClose . wait ()    Seealso  Visit  HTTP \u2192 Client  for more information on setting up an HTTP client.", 
            "title": "Client"
        }, 
        {
            "location": "/websocket/overview/#api-docs", 
            "text": "Check out the  API docs  for more in-depth information about all of the methods.", 
            "title": "API Docs"
        }, 
        {
            "location": "/version/1_5/", 
            "text": "Redirecting...", 
            "title": "1.5"
        }, 
        {
            "location": "/version/1_5/#redirecting", 
            "text": "", 
            "title": "Redirecting..."
        }, 
        {
            "location": "/version/2_0/", 
            "text": "Redirecting...", 
            "title": "2.0"
        }, 
        {
            "location": "/version/2_0/#redirecting", 
            "text": "", 
            "title": "Redirecting..."
        }, 
        {
            "location": "/version/3_0/", 
            "text": "Redirecting...", 
            "title": "3.0"
        }, 
        {
            "location": "/version/3_0/#redirecting", 
            "text": "", 
            "title": "Redirecting..."
        }, 
        {
            "location": "/version/upgrading/", 
            "text": "Upgrading Versions\n\n\nThis document provides information about changes between version and tips for migrating your projects. \n\n\n2.4 to 3.0\n\n\nVapor 3 has been rewritten from the ground up to be async and event-driven. This release contains the most changes of any previous release (and most likely any future release). \n\n\nBecause of this, it is recommended that to migrate your projects you start by creating a new, empty template and migrate by copy / pasting code over to the new project.\n\n\nWe recommend reading the \nGetting Started \n Hello, world!\n section for Vapor 3 to familiarize yourself with the new APIs.\n\n\nAsync\n\n\nThe biggest change in Vapor 3 is that the framework is now completely asynchronous. When you call methods that need to perform slow work like network requests or disk access instead of blocking they will now return a \nFuture\nT\n. \n\n\nFutures are values that may not exist yet, so you cannot interact with them directly. Instead, you must use \nmap\n/\nflatMap\n to access the values.\n\n\n// vapor 2\n\n\nlet\n \nres\n \n=\n \ntry\n \ndrop\n.\nclient\n.\nget\n(\nhttp://vapor.codes\n)\n\n\nprint\n(\nres\n.\nstatus\n)\n \n// HTTPStatus\n\n\nreturn\n \nres\n.\nstatus\n\n\n\n// vapor 3\n\n\nlet\n \nf\n \n=\n \ntry\n \nreq\n.\nclient\n().\nget\n(\nhttp://vapor.codes\n).\nmap\n \n{\n \nres\n \nin\n\n    \nprint\n(\nres\n.\nhttp\n.\nstatus\n)\n \n// HTTPStatus\n\n    \nreturn\n \nres\n.\nhttp\n.\nstatus\n\n\n}\n\n\nprint\n(\nf\n)\n \n// Future\nHTTPStatus\n\n\n\n\n\n\nSee \nAsync \n Getting Started\n to learn more.\n\n\nApplication \n Services\n\n\nDroplet\n has been renamed to \nApplication\n and is now a service-container. In Vapor 2, the \nDroplet\n had stored properties for things you would need during development (like views, hashers, etc). In Vapor 3, this is all done via services. \n\n\nWhile the \nApplication\n \nis\n a service-container, you should not use it from your route closures. This is to prevent race conditions since Vapor runs on multiple threads (event loops). Instead, use the \nRequest\n that is supplied to your route closure. This has a \ncopy\n of all of the application's services for you to use.\n\n\n// vapor 2\n\n\nreturn\n \ntry\n \ndrop\n.\nview\n.\nmake\n(\nmyView\n)\n\n\n\n// vapor 3\n\n\nreturn\n \ntry\n \nreq\n.\nmake\n(\nViewRenderer\n.\nself\n).\nrender\n(\nmyView\n)\n\n\n// shorthand\n\n\nreturn\n \ntry\n \nreq\n.\nview\n().\nrender\n(\nmyView\n)\n\n\n\n\n\n\nSee \nService \n Getting Started\n to learn more.\n\n\nDatabase Connections\n\n\nIn Vapor 3, database connections are no longer statically accessible. This makes doing things like transactions and connection pooling much more predictable and performant. \n\n\nIn order to create a \nQueryBuilder\n in Fluent 3, you will need access to something \nDatabaseConnectable\n. Most often you can just use the incoming \nRequest\n, but you can also create connections manually if you need. \n\n\n// vapor 2\n\n\nUser\n.\nmakeQuery\n().\nall\n()\n\n\n\n// vapor 3\n\n\nUser\n.\nquery\n(\non\n:\n \nreq\n).\nall\n()\n\n\n\n\n\n\nSee \nDatabaseKit \n Getting Started\n to learn more.\n\n\nWork in progress\n\n\nThis migration guide is a work in progress. Please feel free to add any migration tips here by submitting a PR.\n\n\nJoin the \n#upgrading-to-3\n in Vapor's team chat to ask questions and get help in real time.", 
            "title": "Upgrading"
        }, 
        {
            "location": "/version/upgrading/#upgrading-versions", 
            "text": "This document provides information about changes between version and tips for migrating your projects.", 
            "title": "Upgrading Versions"
        }, 
        {
            "location": "/version/upgrading/#24-to-30", 
            "text": "Vapor 3 has been rewritten from the ground up to be async and event-driven. This release contains the most changes of any previous release (and most likely any future release).   Because of this, it is recommended that to migrate your projects you start by creating a new, empty template and migrate by copy / pasting code over to the new project.  We recommend reading the  Getting Started   Hello, world!  section for Vapor 3 to familiarize yourself with the new APIs.", 
            "title": "2.4 to 3.0"
        }, 
        {
            "location": "/version/upgrading/#async", 
            "text": "The biggest change in Vapor 3 is that the framework is now completely asynchronous. When you call methods that need to perform slow work like network requests or disk access instead of blocking they will now return a  Future T .   Futures are values that may not exist yet, so you cannot interact with them directly. Instead, you must use  map / flatMap  to access the values.  // vapor 2  let   res   =   try   drop . client . get ( http://vapor.codes )  print ( res . status )   // HTTPStatus  return   res . status  // vapor 3  let   f   =   try   req . client (). get ( http://vapor.codes ). map   {   res   in \n     print ( res . http . status )   // HTTPStatus \n     return   res . http . status  }  print ( f )   // Future HTTPStatus   See  Async   Getting Started  to learn more.", 
            "title": "Async"
        }, 
        {
            "location": "/version/upgrading/#application-services", 
            "text": "Droplet  has been renamed to  Application  and is now a service-container. In Vapor 2, the  Droplet  had stored properties for things you would need during development (like views, hashers, etc). In Vapor 3, this is all done via services.   While the  Application   is  a service-container, you should not use it from your route closures. This is to prevent race conditions since Vapor runs on multiple threads (event loops). Instead, use the  Request  that is supplied to your route closure. This has a  copy  of all of the application's services for you to use.  // vapor 2  return   try   drop . view . make ( myView )  // vapor 3  return   try   req . make ( ViewRenderer . self ). render ( myView )  // shorthand  return   try   req . view (). render ( myView )   See  Service   Getting Started  to learn more.", 
            "title": "Application &amp; Services"
        }, 
        {
            "location": "/version/upgrading/#database-connections", 
            "text": "In Vapor 3, database connections are no longer statically accessible. This makes doing things like transactions and connection pooling much more predictable and performant.   In order to create a  QueryBuilder  in Fluent 3, you will need access to something  DatabaseConnectable . Most often you can just use the incoming  Request , but you can also create connections manually if you need.   // vapor 2  User . makeQuery (). all ()  // vapor 3  User . query ( on :   req ). all ()   See  DatabaseKit   Getting Started  to learn more.", 
            "title": "Database Connections"
        }, 
        {
            "location": "/version/upgrading/#work-in-progress", 
            "text": "This migration guide is a work in progress. Please feel free to add any migration tips here by submitting a PR.  Join the  #upgrading-to-3  in Vapor's team chat to ask questions and get help in real time.", 
            "title": "Work in progress"
        }, 
        {
            "location": "/version/support/", 
            "text": "Version Support\n\n\n\n\nVapor 3.0 is currently active.\n\n\nVapor 2.4 is being maintained until November 2018.\n\n\nVapor 1.5 is no longer maintained (ended November 2017).\n\n\nCore\n\n\nAll packages in the \nVapor GitHub\n are maintained according to the following rules.\n\n\nActive\n\n\nWhile a version is active, reported security issues and bugs are fixed.\n\n\nAdditionally, new features and optimizations may be added. If new API is added, the minor version number will be incremented. At no point can existing API be removed or broken during an active version. Semver is strictly followed and tested.\n\n\nMaintenance\n\n\nWhen a new version of Vapor is released, the previous version will enter a maintenance phase which lasts for six months. During this phase, critical security issues and bugs will be fixed. No new features will be added.\n\n\n\n\nNote\n\n\nOnly the latest minor version will be maintained.\n\n\n\n\nUnstable\n\n\nThe master branch is the latest development version of Vapor and is constantly changing. Before a new version of Vapor is released, there may be unstable alpha and beta phases in which you are welcome to test and provide feedback on the changes.\n\n\nCommunity\n\n\nAll packages in the \nVapor Community GitHub\n are maintained in strict accordance of semver. Violations of semver should be reported as issues to the offending package's GitHub page.", 
            "title": "Support"
        }, 
        {
            "location": "/version/support/#version-support", 
            "text": "Vapor 3.0 is currently active.  Vapor 2.4 is being maintained until November 2018.  Vapor 1.5 is no longer maintained (ended November 2017).", 
            "title": "Version Support"
        }, 
        {
            "location": "/version/support/#core", 
            "text": "All packages in the  Vapor GitHub  are maintained according to the following rules.", 
            "title": "Core"
        }, 
        {
            "location": "/version/support/#active", 
            "text": "While a version is active, reported security issues and bugs are fixed.  Additionally, new features and optimizations may be added. If new API is added, the minor version number will be incremented. At no point can existing API be removed or broken during an active version. Semver is strictly followed and tested.", 
            "title": "Active"
        }, 
        {
            "location": "/version/support/#maintenance", 
            "text": "When a new version of Vapor is released, the previous version will enter a maintenance phase which lasts for six months. During this phase, critical security issues and bugs will be fixed. No new features will be added.   Note  Only the latest minor version will be maintained.", 
            "title": "Maintenance"
        }, 
        {
            "location": "/version/support/#unstable", 
            "text": "The master branch is the latest development version of Vapor and is constantly changing. Before a new version of Vapor is released, there may be unstable alpha and beta phases in which you are welcome to test and provide feedback on the changes.", 
            "title": "Unstable"
        }, 
        {
            "location": "/version/support/#community", 
            "text": "All packages in the  Vapor Community GitHub  are maintained in strict accordance of semver. Violations of semver should be reported as issues to the offending package's GitHub page.", 
            "title": "Community"
        }
    ]
}