├── .github ├── CODEOWNERS ├── CONTRIBUTING.md ├── dependabot.yml ├── translation_needed.description.leaf └── workflows │ ├── check.yml │ └── deploy.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yaml ├── docs ├── advanced │ ├── apns.es.md │ ├── apns.it.md │ ├── apns.ja.md │ ├── apns.md │ ├── apns.nl.md │ ├── apns.zh.md │ ├── commands.es.md │ ├── commands.ja.md │ ├── commands.md │ ├── commands.nl.md │ ├── commands.zh.md │ ├── files.es.md │ ├── files.ja.md │ ├── files.md │ ├── files.nl.md │ ├── files.zh.md │ ├── middleware.de.md │ ├── middleware.es.md │ ├── middleware.ja.md │ ├── middleware.md │ ├── middleware.nl.md │ ├── middleware.zh.md │ ├── queues.es.md │ ├── queues.ja.md │ ├── queues.md │ ├── queues.nl.md │ ├── queues.zh.md │ ├── request.es.md │ ├── request.it.md │ ├── request.ja.md │ ├── request.md │ ├── request.zh.md │ ├── server.de.md │ ├── server.es.md │ ├── server.ja.md │ ├── server.md │ ├── server.nl.md │ ├── server.zh.md │ ├── services.es.md │ ├── services.ja.md │ ├── services.md │ ├── services.nl.md │ ├── services.zh.md │ ├── sessions.es.md │ ├── sessions.ja.md │ ├── sessions.md │ ├── sessions.nl.md │ ├── sessions.zh.md │ ├── testing.es.md │ ├── testing.it.md │ ├── testing.ja.md │ ├── testing.md │ ├── testing.nl.md │ ├── testing.zh.md │ ├── tracing.es.md │ ├── tracing.ja.md │ ├── tracing.md │ ├── websockets.de.md │ ├── websockets.es.md │ ├── websockets.it.md │ ├── websockets.ja.md │ ├── websockets.md │ ├── websockets.nl.md │ └── websockets.zh.md ├── assets │ ├── favicon.png │ ├── fonts │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-BoldItalic.ttf │ │ ├── Roboto-Italic.ttf │ │ ├── Roboto-Light.ttf │ │ ├── Roboto-LightItalic.ttf │ │ ├── Roboto-Regular.ttf │ │ ├── RobotoMono-Bold.ttf │ │ ├── RobotoMono-BoldItalic.ttf │ │ ├── RobotoMono-Italic.ttf │ │ └── RobotoMono-Regular.ttf │ └── logo.png ├── basics │ ├── async.de.md │ ├── async.es.md │ ├── async.ja.md │ ├── async.md │ ├── async.nl.md │ ├── async.zh.md │ ├── client.es.md │ ├── client.it.md │ ├── client.ja.md │ ├── client.md │ ├── client.nl.md │ ├── client.zh.md │ ├── content.de.md │ ├── content.es.md │ ├── content.ja.md │ ├── content.md │ ├── content.nl.md │ ├── content.zh.md │ ├── controllers.de.md │ ├── controllers.es.md │ ├── controllers.it.md │ ├── controllers.ja.md │ ├── controllers.md │ ├── controllers.nl.md │ ├── controllers.zh.md │ ├── environment.de.md │ ├── environment.es.md │ ├── environment.ja.md │ ├── environment.md │ ├── environment.nl.md │ ├── environment.zh.md │ ├── errors.es.md │ ├── errors.ja.md │ ├── errors.md │ ├── errors.nl.md │ ├── errors.zh.md │ ├── logging.de.md │ ├── logging.es.md │ ├── logging.ja.md │ ├── logging.md │ ├── logging.nl.md │ ├── logging.zh.md │ ├── routing.de.md │ ├── routing.es.md │ ├── routing.ja.md │ ├── routing.md │ ├── routing.nl.md │ ├── routing.zh.md │ ├── validation.de.md │ ├── validation.es.md │ ├── validation.ja.md │ ├── validation.md │ ├── validation.nl.md │ └── validation.zh.md ├── contributing │ ├── contributing.de.md │ ├── contributing.es.md │ ├── contributing.it.md │ ├── contributing.ja.md │ ├── contributing.md │ └── contributing.nl.md ├── deploy │ ├── digital-ocean.es.md │ ├── digital-ocean.ja.md │ ├── digital-ocean.md │ ├── digital-ocean.nl.md │ ├── digital-ocean.zh.md │ ├── docker.es.md │ ├── docker.ja.md │ ├── docker.md │ ├── docker.nl.md │ ├── docker.zh.md │ ├── fly.es.md │ ├── fly.ja.md │ ├── fly.md │ ├── fly.nl.md │ ├── fly.zh.md │ ├── heroku.es.md │ ├── heroku.ja.md │ ├── heroku.md │ ├── heroku.nl.md │ ├── heroku.zh.md │ ├── nginx.es.md │ ├── nginx.ja.md │ ├── nginx.md │ ├── nginx.nl.md │ ├── nginx.zh.md │ ├── supervisor.es.md │ ├── supervisor.ja.md │ ├── supervisor.md │ ├── supervisor.nl.md │ ├── supervisor.zh.md │ ├── systemd.es.md │ ├── systemd.ja.md │ ├── systemd.md │ ├── systemd.nl.md │ └── systemd.zh.md ├── fluent │ ├── advanced.es.md │ ├── advanced.ja.md │ ├── advanced.md │ ├── advanced.nl.md │ ├── advanced.zh.md │ ├── migration.es.md │ ├── migration.it.md │ ├── migration.ja.md │ ├── migration.md │ ├── migration.nl.md │ ├── migration.zh.md │ ├── model.es.md │ ├── model.ja.md │ ├── model.md │ ├── model.nl.md │ ├── model.zh.md │ ├── overview.es.md │ ├── overview.ja.md │ ├── overview.md │ ├── overview.nl.md │ ├── overview.zh.md │ ├── query.es.md │ ├── query.ja.md │ ├── query.md │ ├── query.nl.md │ ├── query.zh.md │ ├── relations.es.md │ ├── relations.ja.md │ ├── relations.md │ ├── relations.nl.md │ ├── relations.zh.md │ ├── schema.es.md │ ├── schema.ja.md │ ├── schema.md │ ├── schema.nl.md │ ├── schema.zh.md │ ├── transaction.es.md │ ├── transaction.fr.md │ ├── transaction.it.md │ ├── transaction.ja.md │ ├── transaction.md │ ├── transaction.nl.md │ └── transaction.zh.md ├── getting-started │ ├── folder-structure.de.md │ ├── folder-structure.es.md │ ├── folder-structure.it.md │ ├── folder-structure.ja.md │ ├── folder-structure.ko.md │ ├── folder-structure.md │ ├── folder-structure.nl.md │ ├── folder-structure.pl.md │ ├── folder-structure.zh.md │ ├── hello-world.de.md │ ├── hello-world.es.md │ ├── hello-world.it.md │ ├── hello-world.ja.md │ ├── hello-world.ko.md │ ├── hello-world.md │ ├── hello-world.nl.md │ ├── hello-world.pl.md │ ├── hello-world.zh.md │ ├── spm.de.md │ ├── spm.es.md │ ├── spm.it.md │ ├── spm.ja.md │ ├── spm.ko.md │ ├── spm.md │ ├── spm.nl.md │ ├── spm.pl.md │ ├── spm.zh.md │ ├── xcode.de.md │ ├── xcode.es.md │ ├── xcode.it.md │ ├── xcode.ja.md │ ├── xcode.ko.md │ ├── xcode.md │ ├── xcode.nl.md │ ├── xcode.pl.md │ └── xcode.zh.md ├── images │ ├── digital-ocean-create-droplet.png │ ├── digital-ocean-distributions-ubuntu.png │ ├── digital-ocean-droplet-list.png │ ├── github-link-issue.png │ ├── swift-download-ubuntu-copy-link.png │ ├── vapor-splash.png │ ├── xcode-mac-app-store.png │ ├── xcode-scheme-area.png │ ├── xcode-scheme-menu.png │ └── xcode-scheme-options.png ├── index.de.md ├── index.es.md ├── index.fr.md ├── index.it.md ├── index.ja.md ├── index.ko.md ├── index.md ├── index.nl.md ├── index.pl.md ├── index.zh.md ├── install │ ├── linux.de.md │ ├── linux.es.md │ ├── linux.it.md │ ├── linux.ja.md │ ├── linux.ko.md │ ├── linux.md │ ├── linux.nl.md │ ├── linux.pl.md │ ├── linux.zh.md │ ├── macos.de.md │ ├── macos.es.md │ ├── macos.it.md │ ├── macos.ja.md │ ├── macos.ko.md │ ├── macos.md │ ├── macos.nl.md │ ├── macos.pl.md │ └── macos.zh.md ├── javascripts │ ├── highlight.min.js │ └── startSyntaxHighlighting.js ├── leaf │ ├── custom-tags.es.md │ ├── custom-tags.it.md │ ├── custom-tags.ja.md │ ├── custom-tags.md │ ├── custom-tags.nl.md │ ├── custom-tags.zh.md │ ├── getting-started.es.md │ ├── getting-started.it.md │ ├── getting-started.ja.md │ ├── getting-started.md │ ├── getting-started.nl.md │ ├── getting-started.pl.md │ ├── getting-started.zh.md │ ├── overview.es.md │ ├── overview.it.md │ ├── overview.ja.md │ ├── overview.md │ ├── overview.nl.md │ └── overview.zh.md ├── redis │ ├── overview.es.md │ ├── overview.it.md │ ├── overview.ja.md │ ├── overview.md │ ├── overview.nl.md │ ├── overview.zh.md │ ├── sessions.es.md │ ├── sessions.it.md │ ├── sessions.ja.md │ ├── sessions.md │ ├── sessions.nl.md │ └── sessions.zh.md ├── release-notes.es.md ├── release-notes.it.md ├── release-notes.ja.md ├── release-notes.md ├── security │ ├── authentication.de.md │ ├── authentication.es.md │ ├── authentication.it.md │ ├── authentication.ja.md │ ├── authentication.md │ ├── authentication.nl.md │ ├── authentication.zh.md │ ├── crypto.es.md │ ├── crypto.it.md │ ├── crypto.ja.md │ ├── crypto.md │ ├── crypto.nl.md │ ├── crypto.zh.md │ ├── jwt.de.md │ ├── jwt.es.md │ ├── jwt.ja.md │ ├── jwt.md │ ├── jwt.nl.md │ ├── jwt.zh.md │ ├── passwords.es.md │ ├── passwords.it.md │ ├── passwords.ja.md │ ├── passwords.md │ ├── passwords.nl.md │ └── passwords.zh.md ├── stylesheets │ ├── fonts.css │ └── syntax.css ├── upgrading.es.md ├── upgrading.it.md ├── upgrading.ja.md ├── upgrading.md ├── upgrading.nl.md └── version │ ├── legacy-docs.es.md │ ├── legacy-docs.it.md │ ├── legacy-docs.ja.md │ ├── legacy-docs.md │ └── legacy-docs.nl.md ├── fixSearchIndex.swift ├── googlefc012e5d94cfa05f.html ├── markdown-link-check-config.yml ├── mkdocs.yml ├── requirements.txt ├── setUpRedirects.swift ├── stack.yml └── theme ├── 404.html ├── main.html ├── scripts └── carbon.js └── styles └── carbon.css /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @0xTim @gwynne 2 | docs/**/*.??.md @vapor/Translators 3 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Vapor Docs 2 | 3 | Found a mistake or want to add something? Fork the documentation, fix it, and submit a pull request. 4 | 5 | We'll merge it as soon as we can. 6 | 7 | Thanks! 8 | 9 | ## Developing 10 | 11 | ### 1.0 12 | 13 | Install `couscous` through Composer and run `couscous preview` 14 | 15 | ### 2.0+ 16 | 17 | Install Homebrew. 18 | 19 | See [Homebrew](https://brew.sh) 20 | 21 | Install Python 3. 22 | 23 | ```sh 24 | brew install python3 25 | ``` 26 | 27 | Install MkDocs and MkDocs Material theme. 28 | 29 | ```sh 30 | pip3 install mkdocs 31 | pip3 install mkdocs-material 32 | ``` 33 | 34 | Run with `mkdocs serve` 35 | 36 | ## Testing 37 | 38 | If you want to check dead links, use markdown-link-check 39 | 40 | ```sh 41 | npm install --save-dev markdown-link-check 42 | ``` 43 | 44 | Run with 45 | 46 | ```sh 47 | find . -name \*.md -print0 | xargs -0 -n1 markdown-link-check -q -c markdown-link-check-config.yml 48 | ``` 49 | on directly under the repository. 50 | 51 | 52 | OR 53 | 54 | Run docker directly under the repository 55 | 56 | ```sh 57 | docker run -v ${PWD}:/tmp:ro --rm -i --entrypoint "sh" ghcr.io/tcort/markdown-link-check:stable "-c" "find /tmp -name \*.md -print0 | xargs -0 -n1 markdown-link-check -q -c /tmp/markdown-link-check-config.yml" 58 | ``` 59 | 60 | 61 | 62 | ### Maintainers 63 | - [@0xtim](https://github.com/0xTim) 64 | - [@mcdappdev](https://github.com/mcdappdev) 65 | 66 | See https://github.com/vapor/vapor/blob/main/.github/maintainers.md for more information. 67 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | groups: 8 | dependencies: 9 | patterns: 10 | - "*" 11 | - package-ecosystem: "pip" 12 | directory: "/" 13 | schedule: 14 | interval: "daily" 15 | groups: 16 | dependencies: 17 | patterns: 18 | - "*" 19 | -------------------------------------------------------------------------------- /.github/translation_needed.description.leaf: -------------------------------------------------------------------------------- 1 | The docs have been updated in PR ##(number). The translations should be updated if required. 2 | 3 | Languages: 4 | - [ ] English 5 | - [ ] Deutsch (German) 6 | - [ ] Español (Spanish) 7 | - [ ] Français (French) 8 | - [ ] Italiano (Italian) 9 | - [ ] 日本語 (Japanese) 10 | - [ ] 한국어 (Korean) 11 | - [ ] Nederlands (Dutch) 12 | - [ ] Polski (Polish) 13 | - [ ] 简体中文 (Simplified Chinese) 14 | 15 | Assigned to @vapor/translators - please submit a PR with the relevant updates and check the box once merged. 16 | Please ensure you tag your PR with the `translation-update` so it doesn't create a new issue! 17 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: Build docs and check cloudformation and dead links 2 | concurrency: 3 | group: ${{ github.workflow }}-${{ github.ref }} 4 | cancel-in-progress: true 5 | on: 6 | pull_request: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | check: 12 | name: build docs 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v4 17 | - name: Create virtual environment 18 | run: python3 -m venv venv 19 | - name: Install dependencies 20 | run: venv/bin/pip install -r requirements.txt 21 | - name: Build documentation 22 | run: venv/bin/mkdocs build 23 | - name: Setup cloudformation linter 24 | uses: ScottBrenner/cfn-lint-action@v2 25 | - name: Run cloudformation lint 26 | run: cfn-lint -t stack.yml 27 | - name: Check dead links 28 | uses: gaurav-nelson/github-action-markdown-link-check@v1 29 | with: 30 | folder-path: '.' 31 | config-file: 'markdown-link-check-config.yml' 32 | use-verbose-mode: 'yes' 33 | use-quiet-mode: 'yes' 34 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Build and deploy the Vapor documentation 2 | concurrency: 3 | group: ${{ github.workflow }}-${{ github.ref }} 4 | cancel-in-progress: true 5 | on: 6 | push: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | deploy: 12 | name: Build and deploy 13 | runs-on: ubuntu-latest 14 | permissions: { id-token: write, contents: read } 15 | env: { AWS_PAGER: '' } 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v4 19 | 20 | - name: Create virtual environment 21 | run: python3 -m venv venv 22 | - name: Install dependencies 23 | run: venv/bin/pip install -r requirements.txt 24 | - name: Build the website 25 | run: | 26 | venv/bin/mkdocs build 27 | swift fixSearchIndex.swift 28 | cp googlefc012e5d94cfa05f.html site/googlefc012e5d94cfa05f.html 29 | swift setUpRedirects.swift 30 | 31 | - name: Configure AWS credentials 32 | uses: aws-actions/configure-aws-credentials@v4 33 | with: 34 | role-to-assume: ${{ vars.OIDC_ROLE_ARN }} 35 | aws-region: ${{ vars.OIDC_ROLE_REGION }} 36 | - name: Deploy CloudFormation stack 37 | uses: aws-actions/aws-cloudformation-github-deploy@v1 38 | with: 39 | name: vapor-docs-stack 40 | template: stack.yml 41 | no-fail-on-empty-changeset: '1' 42 | parameter-overrides: >- 43 | DomainName=docs.vapor.codes, 44 | S3BucketName=${{ secrets.DOCS_S3_BUCKET_NAME }}, 45 | AcmCertificateArn=${{ secrets.CERTIFICATE_ARN }} 46 | - name: Upload data to S3 47 | run: | 48 | aws s3 sync ./site 's3://${{ secrets.DOCS_S3_BUCKET_NAME }}' --no-progress --acl public-read 49 | - name: Invalidate CloudFront 50 | run: | 51 | aws cloudfront create-invalidation --distribution-id '${{ secrets.DOCS_DISTRIBUTION_ID }}' --paths '/*' 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache 2 | .DS_Store 3 | /site 4 | 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swift:5.10 2 | 3 | RUN apt-get update && apt-get install -y python3-pip 4 | 5 | COPY requirements.txt . 6 | 7 | RUN pip3 install -r requirements.txt 8 | 9 | WORKDIR /docs 10 | 11 | COPY . . 12 | 13 | RUN mkdocs build 14 | RUN swift fixSearchIndex.swift 15 | RUN cp googlefc012e5d94cfa05f.html site/googlefc012e5d94cfa05f.html; 16 | RUN swift setUpRedirects.swift 17 | 18 | EXPOSE 8000 19 | 20 | CMD [ "mkdocs","serve","-a","0.0.0.0:8000"] 21 | 22 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | docs: 3 | build: ./ 4 | image: vapor/docs 5 | container_name: vapor-docs 6 | ports: 7 | - "8000:8000" 8 | volumes: 9 | - type: bind 10 | source: ./ 11 | target: /docs -------------------------------------------------------------------------------- /docs/advanced/files.ja.md: -------------------------------------------------------------------------------- 1 | # ファイル {#files} 2 | 3 | Vaporは、ルートハンドラ内でファイルを非同期に読み書きするためのシンプルなAPIを提供しています。このAPIは、NIOの[`NonBlockingFileIO`](https://swiftpackageindex.com/apple/swift-nio/main/documentation/nioposix/nonblockingfileio)型の上に構築されています。 4 | 5 | ## 読み取り {#read} 6 | 7 | ファイルを読み取るための主要なメソッドは、ディスクから読み取られたチャンクをコールバックハンドラに配信します。読み取るファイルはパスで指定します。相対パスは、プロセスの現在の作業ディレクトリを参照します。 8 | 9 | ```swift 10 | // ディスクからファイルを非同期に読み取ります。 11 | let readComplete: EventLoopFuture = req.fileio.readFile(at: "/path/to/file") { chunk in 12 | print(chunk) // ByteBuffer 13 | } 14 | 15 | // または 16 | 17 | try await req.fileio.readFile(at: "/path/to/file") { chunk in 18 | print(chunk) // ByteBuffer 19 | } 20 | // 読み取り完了 21 | ``` 22 | 23 | `EventLoopFuture`を使用している場合、返されたfutureは読み取りが完了したか、エラーが発生したときにシグナルを送ります。`async`/`await`を使用している場合、`await`が返ると読み取りが完了しています。エラーが発生した場合は、エラーをスローします。 24 | 25 | ### ストリーム {#stream} 26 | 27 | `streamFile`メソッドは、ストリーミングファイルを`Response`に変換します。このメソッドは、`ETag`や`Content-Type`などの適切なヘッダーを自動的に設定します。 28 | 29 | ```swift 30 | // ファイルを非同期にHTTPレスポンスとしてストリームします。 31 | req.fileio.streamFile(at: "/path/to/file").map { res in 32 | print(res) // Response 33 | } 34 | 35 | // または 36 | 37 | let res = req.fileio.streamFile(at: "/path/to/file") 38 | print(res) 39 | 40 | ``` 41 | 42 | 結果は、ルートハンドラから直接返すことができます。 43 | 44 | ### 収集 {#collect} 45 | 46 | `collectFile`メソッドは、指定されたファイルをバッファに読み込みます。 47 | 48 | ```swift 49 | // ファイルをバッファに読み込みます。 50 | req.fileio.collectFile(at: "/path/to/file").map { buffer in 51 | print(buffer) // ByteBuffer 52 | } 53 | 54 | // または 55 | 56 | let buffer = req.fileio.collectFile(at: "/path/to/file") 57 | print(buffer) 58 | ``` 59 | 60 | !!! warning 61 | このメソッドは、ファイル全体を一度にメモリに読み込む必要があります。メモリ使用量を制限するには、チャンクまたはストリーミング読み取りを使用してください。 62 | 63 | ## 書き込み {#write} 64 | 65 | `writeFile`メソッドは、バッファをファイルに書き込むことをサポートしています。 66 | 67 | ```swift 68 | // バッファをファイルに書き込みます。 69 | req.fileio.writeFile(ByteBuffer(string: "Hello, world"), at: "/path/to/file") 70 | ``` 71 | 72 | 返されたfutureは、書き込みが完了したか、エラーが発生したときにシグナルを送ります。 73 | 74 | ## ミドルウェア {#middleware} 75 | 76 | プロジェクトの_Public_フォルダから自動的にファイルを提供する方法の詳細については、[ミドルウェア → FileMiddleware](middleware.md#file-middleware)を参照してください。 77 | 78 | ## 高度な使い方 {#advanced} 79 | 80 | VaporのAPIがサポートしていないケースでは、NIOの`NonBlockingFileIO`型を直接使用できます。 81 | 82 | ```swift 83 | // メインスレッド。 84 | let fileHandle = try await app.fileio.openFile( 85 | path: "/path/to/file", 86 | eventLoop: app.eventLoopGroup.next() 87 | ).get() 88 | print(fileHandle) 89 | 90 | // ルートハンドラ内。 91 | let fileHandle = try await req.application.fileio.openFile( 92 | path: "/path/to/file", 93 | eventLoop: req.eventLoop) 94 | print(fileHandle) 95 | ``` 96 | 97 | 詳細については、SwiftNIOの[APIリファレンス](https://swiftpackageindex.com/apple/swift-nio/main/documentation/nioposix/nonblockingfileio)をご覧ください。 -------------------------------------------------------------------------------- /docs/advanced/files.zh.md: -------------------------------------------------------------------------------- 1 | # 文件 2 | 3 | Vapor 提供了基于 [NIO](https://swiftpackageindex.com/apple/swift-nio/main/documentation/nioposix/nonblockingfileio) 构建的 API,用于异步处理路由内部的文件读取和写入。 4 | 5 | ## 读取 6 | 7 | 读取文件的主要方法在从磁盘读取块时将块传递给回调处理程序。要读取的文件由其路径指定。相对路径将在进程的当前工作目录中查找。 8 | 9 | ```swift 10 | // 异步地从磁盘读取文件。 11 | let readComplete: EventLoopFuture = req.fileio.readFile(at: "/path/to/file") { chunk in 12 | print(chunk) // ByteBuffer 13 | } 14 | 15 | // 或者 16 | 17 | try await req.fileio.readFile(at: "/path/to/file") { chunk in 18 | print(chunk) // ByteBuffer 19 | } 20 | // 读取完成 21 | ``` 22 | 23 | 如果使用 `EventLoopFutures`,则读取完成或发生错误时,返回的 future 将发出信号。如果使用 `async`/`await` 则一旦 `await` 返回,读取就完成了。如果发生错误,它会抛出一个错误。 24 | 25 | ### 流 26 | 27 | `streamFile` 方法将文件流转换为 `Response`。 此方法将自动设置适当的响应头,例如 `ETag` 和 `Content-Type`。 28 | 29 | ```swift 30 | // 异步流文件作为HTTP响应。 31 | req.fileio.streamFile(at: "/path/to/file").map { res in 32 | print(res) // 响应 33 | } 34 | 35 | // 或者 36 | 37 | let res = req.fileio.streamFile(at: "/path/to/file") 38 | print(res) 39 | 40 | ``` 41 | 42 | 路由处理程序可以直接将结果返回。 43 | 44 | ### Collect 45 | 46 | `collectFile` 方法将指定的文件读入缓冲区。 47 | 48 | ```swift 49 | // 去读文件到缓冲区 50 | req.fileio.collectFile(at: "/path/to/file").map { buffer in 51 | print(buffer) // ByteBuffer 52 | } 53 | 54 | // 或者 55 | 56 | let buffer = req.fileio.collectFile(at: "/path/to/file") 57 | print(buffer) 58 | ``` 59 | 60 | !!! warning "警告" 61 | 此方法要求整个文件一次性加载到内存中。使用分块或流式读取来限制内存使用。 62 | 63 | ## 写入 64 | 65 | `writeFile` 方法支持将缓冲区数据写入文件。 66 | 67 | ```swift 68 | // 将缓冲区数据写入文件 69 | req.fileio.writeFile(ByteBuffer(string: "Hello, world"), at: "/path/to/file") 70 | ``` 71 | 72 | 当写入完成或发生错误时,返回的 future 将发出信号。 73 | 74 | ## 中间件 75 | 76 | 了解关于从项目的 _Public_ 文件夹自动提供文件的更多信息,请参阅 [中间件 → 文件中间件](middleware.zh.md#file-middleware)。 77 | 78 | ## 进阶 79 | 80 | 对于 Vapor API 不支持的情况,你可以直接使用 NIO 的 `NonBlockingFileIO` 类型。 81 | 82 | ```swift 83 | // 主线程。 84 | let fileHandle = try await app.fileio.openFile( 85 | path: "/path/to/file", 86 | eventLoop: app.eventLoopGroup.next() 87 | ).get() 88 | print(fileHandle) 89 | 90 | // 在路由处理程序中。 91 | let fileHandle = try await req.application.fileio.openFile( 92 | path: "/path/to/file", 93 | eventLoop: req.eventLoop) 94 | print(fileHandle) 95 | ``` 96 | 97 | 了解更多信息,请参阅 SwiftNIO 的 [API 文档](https://swiftpackageindex.com/apple/swift-nio/main/documentation/nioposix/nonblockingfileio)。 98 | -------------------------------------------------------------------------------- /docs/advanced/request.zh.md: -------------------------------------------------------------------------------- 1 | # Request 2 | 3 | [`Request`](https://api.vapor.codes/vapor/documentation/vapor/request) 对象被传递到每一个[路由处理程序](../basics/routing.md)中. 4 | 5 | ```swift 6 | app.get("hello", ":name") { req -> String in 7 | let name = req.parameters.get("name")! 8 | return "Hello, \(name)!" 9 | } 10 | ``` 11 | 12 | 它是进入 Vapor 的主要窗口。包含了用于 [请求体](../basics/content.md),[查询参数](../basics/content.md#query),[日志记录器](../basics/logging.md),[HTTP 客户端](../basics/client.md),[认证器](../security/authentication.md), 等的 API。 通过请求访问这些功能可以将计算保持在正确的事件循环中,并允许在测试中进行模拟。你甚至可以通过扩展将自己的[服务](../advanced/services.md)添加到 `Request` 中。 13 | 14 | 完整的 `Request` API 文档可以在[这里](https://api.vapor.codes/vapor/documentation/vapor/request)找到。 15 | 16 | ## Application 17 | 18 | `Request.application` 属性持有对 [`Application`](https://api.vapor.codes/vapor/documentation/vapor/application) 的引用。 这个对象包含了应用程序的所有配置和核心功能。大部分配置应该只在 `configure.swift` 中设置,在应用程序完全启动之前进行,许多较低级别的 API 在大多数应用程序中都不会被使用。其中最有用的属性之一 `Application.eventLoopGroup`,它可以通过 `any()` 方法用于需要新的 `EventLoop` 的进程中获取。它还包含了 [`Environment`](../basics/environment.md)。 19 | 20 | ## Body 21 | 22 | 如果你想以 `ByteBuffer` 的形式直接访问请求体,可以使用 `Request.body.data`。这可以用于从请求体流式传输数据到文件(尽管在这种情况下应该使用请求的 [fileio](../advanced/files.md) 属性),或者传输到另一个 HTTP 客户端。 23 | 24 | ## Cookies 25 | 26 | 虽然最常见的 cookie 应用是通过内置的[会话](../advanced/sessions.md#configuration)进行的,但你也可以通过 `Request.cookies` 直接访问 cookie。 27 | 28 | ```swift 29 | app.get("my-cookie") { req -> String in 30 | guard let cookie = req.cookies["my-cookie"] else { 31 | throw Abort(.badRequest) 32 | } 33 | if let expiration = cookie.expires, expiration < Date() { 34 | throw Abort(.badRequest) 35 | } 36 | return cookie.string 37 | } 38 | ``` 39 | 40 | ## Headers 41 | 42 | 通过 `Request.headers` 访问一个 `HTTPHeaders` 对象,其中包含了与请求一起发送的所有标头。例如,可以使用它来访问 `Content-Type` 标头。 43 | 44 | ```swift 45 | app.get("json") { req -> String in 46 | guard let contentType = req.headers.contentType, contentType == .json else { 47 | throw Abort(.badRequest) 48 | } 49 | return "JSON" 50 | } 51 | ``` 52 | 53 | 进一步了解 `HTTPHeaders` 的文档,请参阅[此处](https://swiftpackageindex.com/apple/swift-nio/2.56.0/documentation/niohttp1/httpheaders)。Vapor 还为 `HTTPHeaders` 添加了几个扩展,以便更轻松地处理最常用的标头;你可以在[此处](https://api.vapor.codes/vapor/documentation/vapor/niohttp1/httpheaders#instance-properties)找到扩展列表。 54 | 55 | ## IP Address 56 | 57 | 代表客户端的 `SocketAddress` 可以通过 `Request.remoteAddress` 访问,这可能对于日志记录或使用字符串表示的 `Request.remoteAddress.ipAddress` 进行速率限制很有用。如果应用程序在反向代理后面,则可能无法准确表示客户端的 IP 地址。 58 | 59 | ```swift 60 | app.get("ip") { req -> String in 61 | return req.remoteAddress.ipAddress 62 | } 63 | ``` 64 | 65 | 了解更多 `SocketAddress` 文档,请参阅[此处](https://swiftpackageindex.com/apple/swift-nio/2.56.0/documentation/niocore/socketaddress)。 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /docs/advanced/testing.zh.md: -------------------------------------------------------------------------------- 1 | # 测试 2 | 3 | Vapor 包含一个名为 `XCTVapor` 的模块,它提供了基于 `XCTest` 的测试帮助程序。这些测试辅助程序允许你以编程方式或通过 HTTP 服务器将测试请求发送至 Vapor 应用程序。 4 | 5 | ## 入门 6 | 7 | 要使用 `XCTVapor` 模块,请确保在你的项目 `Package.swift` 文件已添加了对应的 **testTarget**。 8 | 9 | ```swift 10 | let package = Package( 11 | ... 12 | dependencies: [ 13 | .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0") 14 | ], 15 | targets: [ 16 | ... 17 | .testTarget(name: "AppTests", dependencies: [ 18 | .target(name: "App"), 19 | .product(name: "XCTVapor", package: "vapor"), 20 | ]) 21 | ] 22 | ) 23 | ``` 24 | 25 | 然后,在测试文件的顶部添加 `import XCTVapor`,创建继承于 `XCTestCase` 的子类来编写测试用例。 26 | 27 | ```swift 28 | import XCTVapor 29 | 30 | final class MyTests: XCTestCase { 31 | func testStub() throws { 32 | // 在这里测试。 33 | } 34 | } 35 | ``` 36 | 37 | 当你的应用程序执行测试时,每个以 `test` 开头的函数都会自动运行。 38 | 39 | ### 运行测试 40 | 41 | 在使用 `Package` 方案的情况下,使用 `cmd+u` 在 Xcode 中运行测试用例。 42 | 或使用 `swift test --enable-test-discovery` 通过 CLI 进行测试。 43 | 44 | ## 可测试的应用程序 45 | 46 | 使用 `.testing` 环境初始化一个 `Application` 的实例。在此应用程序被销毁之前,你必须调用 `app.shutdown()`。关闭操作是为了释放应用程序所占用的资源。特别重要的是释放应用程序在启动时请求的线程。如果你在每个单元测试后没有调用 `shutdown()` 方法,可能会在为 `Application` 的新实例分配线程时导致测试套件崩溃,出现先决条件失败。 47 | 48 | ```swift 49 | let app = Application(.testing) 50 | defer { app.shutdown() } 51 | try configure(app) 52 | ``` 53 | 54 | 将 `Application` 实例对象作为入参传到 `configure(_:)` 方法来应用你的配置,之后可以应用到任何仅测试的配置。 55 | 56 | ### 发送请求 57 | 58 | 要向你的应用程序发送一个测试请求,请使用 `test` 方法。 59 | 60 | ```swift 61 | try app.test(.GET, "hello") { res in 62 | XCTAssertEqual(res.status, .ok) 63 | XCTAssertEqual(res.body.string, "Hello, world!") 64 | } 65 | ``` 66 | 67 | 前两个参数是 HTTP 方法和请求的 URL。后面的尾随闭包接受 HTTP 响应,你可以使用 `XCTAssert` 方法进行验证。 68 | 69 | 对于更复杂的请求,你可以提供一个 `beforeRequest` 闭包来修改请求头或编码内容。Vapor 的 [Content API](../basics/content.md) 可以在测试请求和响应中使用。 70 | 71 | ```swift 72 | try app.test(.POST, "todos", beforeRequest: { req in 73 | try req.content.encode(["title": "Test"]) 74 | }, afterResponse: { res in 75 | XCTAssertEqual(res.status, .created) 76 | let todo = try res.content.decode(Todo.self) 77 | XCTAssertEqual(todo.title, "Test") 78 | }) 79 | ``` 80 | 81 | ### 可测试的方法 82 | 83 | Vapor 的测试 API 支持以编程方式并通过实时 HTTP 服务器发送测试请求。 84 | 你可以通过使用 `testable` 方法来指定你想要使用的方法。 85 | 86 | ```swift 87 | // 使用程序化测试。 88 | app.testable(method: .inMemory).test(...) 89 | 90 | // 通过一个实时的 HTTP 服务器运行测试。 91 | app.testable(method: .running).test(...) 92 | ``` 93 | 94 | 默认情况下使用 `inMemory` 选项。 95 | 96 | `running` 选项支持传递一个特定的端口来使用。默认情况下使用的是 `8080`。 97 | 98 | ```swift 99 | .running(port: 8123) 100 | ``` 101 | 102 | 当然,你也可以修改为其他端口进行测试。 103 | -------------------------------------------------------------------------------- /docs/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/favicon.png -------------------------------------------------------------------------------- /docs/assets/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/Roboto-Italic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/Roboto-Light.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/RobotoMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/RobotoMono-Bold.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/RobotoMono-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/RobotoMono-BoldItalic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/RobotoMono-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/RobotoMono-Italic.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/RobotoMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/fonts/RobotoMono-Regular.ttf -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/basics/client.es.md: -------------------------------------------------------------------------------- 1 | # Cliente 2 | 3 | La API cliente de Vapor te permite hacer llamadas HTTP a recursos externos. Está hecha en [async-http-client](https://github.com/swift-server/async-http-client) y se integra con la API [content](content.md). 4 | 5 | ## Descripción 6 | 7 | Puedes acceder al cliente por defecto mediante `Application`, o en un controlador de rutas mediante `Request`. 8 | 9 | ```swift 10 | app.client // Cliente 11 | 12 | app.get("test") { req in 13 | req.client // Cliente 14 | } 15 | ``` 16 | 17 | El cliente de la aplicación es útil para realizar peticiones HTTP durante la configuración. Si realizas las peticiones HTTP en un controlador de rutas, usa siempre el cliente de la petición (request). 18 | 19 | ### Métodos 20 | 21 | Para realizar una petición `GET`, proporciona la URL deseada al método de conveniencia `get`. 22 | 23 | ```swift 24 | let response = try await req.client.get("https://httpbin.org/status/200") 25 | ``` 26 | 27 | Existen métodos para cada acción HTTP, como `get`, `post`, y `delete`. La respuesta del cliente es devuelta como un futuro y contiene el estado (status) HTTP, las cabeceras y el cuerpo de la petición. 28 | 29 | ### Content 30 | 31 | La API [content](content.md) de Vapor está disponible para el manejo de datos en las peticiones y respuestas del cliente. Para codificar contenido, parámetros de petición o añadir cabeceras a la petición, usa el closure `beforeSend`. 32 | 33 | ```swift 34 | let response = try await req.client.post("https://httpbin.org/status/200") { req in 35 | // Codifica la cadena de consulta (query) a la petición URL. 36 | try req.query.encode(["q": "test"]) 37 | 38 | // Codifica un JSON en el cuerpo de la petición. 39 | try req.content.encode(["hello": "world"]) 40 | 41 | // Añade una cabecera de autenticación a la petición. 42 | let auth = BasicAuthorization(username: "something", password: "somethingelse") 43 | req.headers.basicAuthorization = auth 44 | } 45 | // Controla la respuesta. 46 | ``` 47 | 48 | También puedes decodificar el cuerpo de la respuesta usando `Content` de manera similar: 49 | 50 | ```swift 51 | let response = try await req.client.get("https://httpbin.org/json") 52 | let json = try response.content.decode(MyJSONResponse.self) 53 | ``` 54 | 55 | Si estás utilizando futuros, puedes usar `flatMapThrowing`: 56 | 57 | ```swift 58 | return req.client.get("https://httpbin.org/json").flatMapThrowing { res in 59 | try res.content.decode(MyJSONResponse.self) 60 | }.flatMap { json in 61 | // Usa JSON aquí 62 | } 63 | ``` 64 | 65 | ## Configuración 66 | 67 | Puedes configurar el cliente HTTP subyacente mediante la aplicación. 68 | 69 | ```swift 70 | // Desactiva el seguimiento de redireccionado automático. 71 | app.http.client.configuration.redirectConfiguration = .disallow 72 | ``` 73 | 74 | Ten en cuenta que debes configurar el cliente por defecto _antes_ de usarlo por primera vez. 75 | 76 | -------------------------------------------------------------------------------- /docs/basics/client.it.md: -------------------------------------------------------------------------------- 1 | # Client 2 | 3 | L'API client di Vapor ti permette di fare chiamate HTTP a risorse esterne. Si basa su [async-http-client](https://github.com/swift-server/async-http-client) e si integra con l'API [content](content.md). 4 | 5 | ## Panoramica 6 | 7 | Puoi accedere al client di default attraverso `Application` o in un handler di route attraverso `Request`. 8 | 9 | ```swift 10 | app.client // Client 11 | 12 | app.get("test") { req in 13 | req.client // Client 14 | } 15 | ``` 16 | 17 | Il client dell'applicazione è utile per fare richieste HTTP durante la configurazione. Se fai richieste HTTP in un handler di route, usa sempre il client della richiesta. 18 | 19 | ### Metodi 20 | 21 | Per fare una richiesta `GET`, passa l'URL desiderato al comodo metodo `get`. 22 | 23 | ```swift 24 | let response = try await req.client.get("https://httpbin.org/status/200") 25 | ``` 26 | 27 | Ci sono metodi per ogni verbo HTTP come `get`, `post`, e `delete`. La risposta del client viene ritornata come future e contiene lo stato, l'header, e il corpo HTTP. 28 | 29 | ### Contenuto 30 | 31 | L'API [content](content.md) di Vapor è disponibile per gestire i dati nelle richieste e nelle risposte del client. Per codificare il contenuto, parametri della query o aggiungere header alla richiesta, usa la closure `beforeSend`. 32 | 33 | ```swift 34 | let response = try await req.client.post("https://httpbin.org/status/200") { req in 35 | // Codifica la stringa di query all'URL della richiesta. 36 | try req.query.encode(["q": "test"]) 37 | 38 | // Codifica il JSON per il corpo della richiesta. 39 | try req.content.encode(["hello": "world"]) 40 | 41 | // Aggiungi l'header di autenticazione alla richiesta 42 | let auth = BasicAuthorization(username: "something", password: "somethingelse") 43 | req.headers.basicAuthorization = auth 44 | } 45 | // Gestisci la risposta. 46 | ``` 47 | 48 | Puoi anche decodificare il corpo della risposta usando `Content` in modo simile: 49 | 50 | ```swift 51 | let response = try await req.client.get("https://httpbin.org/json") 52 | let json = try response.content.decode(MyJSONResponse.self) 53 | ``` 54 | 55 | Se usi i future puoi usare `flatMapThrowing`: 56 | 57 | ```swift 58 | return req.client.get("https://httpbin.org/json").flatMapThrowing { res in 59 | try res.content.decode(MyJSONResponse.self) 60 | }.flatMap { json in 61 | // Usa il JSON qui 62 | } 63 | ``` 64 | 65 | ## Configurazione 66 | 67 | Puoi configurare il client HTTP sottostante tramite l'applicazione. 68 | 69 | ```swift 70 | // Disabilita il redirect automatico seguente. 71 | app.http.client.configuration.redirectConfiguration = .disallow 72 | ``` 73 | 74 | Nota che devi configurare il client di default _prima_ di usarlo per la prima volta. 75 | 76 | 77 | -------------------------------------------------------------------------------- /docs/basics/client.ja.md: -------------------------------------------------------------------------------- 1 | # クライアント {#client} 2 | 3 | Vapor のクライアント API では、外部のリソースに対して HTTP 通信を行うことができます。これは [async-http-client](https://github.com/swift-server/async-http-client) に基づいており、[コンテンツ](content.ja.md) API と統合されています。 4 | 5 | ## 概要 {#overview} 6 | 7 | `Application` やルートハンドラー内の `Request` から、デフォルトクライアントにアクセスできます。 8 | 9 | ```swift 10 | app.client // Client 11 | 12 | app.get("test") { req in 13 | req.client // Client 14 | } 15 | ``` 16 | 17 | アプリケーションのクライアントは、設定時に HTTP リクエストを送る際に便利です。ルートハンドラー内で HTTP リクエストを行う場合は、リクエストに紐づくクライアントを使うべきです。 18 | 19 | ### メソッド {#methods} 20 | 21 | `GET` リクエストを行う際には、目的の URL を `get` メソッドに渡します。 22 | 23 | ```swift 24 | let response = try await req.client.get("https://httpbin.org/status/200") 25 | ``` 26 | 27 | `get`、`post`、`delete` など、各種 HTTP メソッドに対応したメソッドがあります。クライアントからのレスポンスはFutureとして返され、HTTPステータス、ヘッダー、ボディが含まれます。 28 | 29 | ### コンテンツ {#content} 30 | 31 | Vapor の [コンテンツ](content.ja.md) を使うと、クライアントリクエストやレスポンスのデータを扱うことができます。コンテンツやクエリパラメータをエンコードしたり、ヘッダーを追加するには、`beforeSend` クロージャを使います。 32 | 33 | ```swift 34 | let response = try await req.client.post("https://httpbin.org/status/200") { req in 35 | // リクエストURLにクエリ文字列をエンコードします。 36 | try req.query.encode(["q": "test"]) 37 | 38 | // JSONをリクエストボディにエンコードします。 39 | try req.content.encode(["hello": "world"]) 40 | 41 | // リクエストに認証ヘッダーを追加します。 42 | let auth = BasicAuthorization(username: "something", password: "somethingelse") 43 | req.headers.basicAuthorization = auth 44 | } 45 | // レスポンスを処理する。 46 | ``` 47 | 48 | レスポンスボディを `Content` を使ってデコードすることもできます。 49 | 50 | ```swift 51 | let response = try await req.client.get("https://httpbin.org/json") 52 | let json = try response.content.decode(MyJSONResponse.self) 53 | ``` 54 | 55 | もし、Future を使っている場合は、`flatMapThrowing` を使うことができます。 56 | 57 | ```swift 58 | return req.client.get("https://httpbin.org/json").flatMapThrowing { res in 59 | try res.content.decode(MyJSONResponse.self) 60 | }.flatMap { json in 61 | // ここでJSONを使用 62 | } 63 | ``` 64 | 65 | ## 設定 {#configuration} 66 | 67 | アプリケーションを通じて、基本となる HTTP クライアントを設定することができます。 68 | 69 | ```swift 70 | // 自動リダイレクトを無効にする。 71 | app.http.client.configuration.redirectConfiguration = .disallow 72 | ``` 73 | 74 | 初めてデフォルトクライアントを使用する前に、必ず設定を完了させておく必要があります。 75 | -------------------------------------------------------------------------------- /docs/basics/client.md: -------------------------------------------------------------------------------- 1 | # Client 2 | 3 | Vapor's client API allows you to make HTTP calls to external resources. It is built on [async-http-client](https://github.com/swift-server/async-http-client) and integrates with the [content](content.md) API. 4 | 5 | ## Overview 6 | 7 | You can get access to the default client via `Application` or in a route handler via `Request`. 8 | 9 | ```swift 10 | app.client // Client 11 | 12 | app.get("test") { req in 13 | req.client // Client 14 | } 15 | ``` 16 | 17 | The application's client is useful for making HTTP requests during configuration time. If you are making HTTP requests in a route handler, always use the request's client. 18 | 19 | ### Methods 20 | 21 | To make a `GET` request, pass the desired URL to the `get` convenience method. 22 | 23 | ```swift 24 | let response = try await req.client.get("https://httpbin.org/status/200") 25 | ``` 26 | 27 | There are methods for each of the HTTP verbs like `get`, `post`, and `delete`. The client's response is returned as a future and contains the HTTP status, headers, and body. 28 | 29 | ### Content 30 | 31 | Vapor's [content](content.md) API is available for handling data in client requests and responses. To encode content, query parameters or add headers to the request, use the `beforeSend` closure. 32 | 33 | ```swift 34 | let response = try await req.client.post("https://httpbin.org/status/200") { req in 35 | // Encode query string to the request URL. 36 | try req.query.encode(["q": "test"]) 37 | 38 | // Encode JSON to the request body. 39 | try req.content.encode(["hello": "world"]) 40 | 41 | // Add auth header to the request 42 | let auth = BasicAuthorization(username: "something", password: "somethingelse") 43 | req.headers.basicAuthorization = auth 44 | } 45 | // Handle the response. 46 | ``` 47 | 48 | You can also decode the response body using `Content` in a similar way: 49 | 50 | ```swift 51 | let response = try await req.client.get("https://httpbin.org/json") 52 | let json = try response.content.decode(MyJSONResponse.self) 53 | ``` 54 | 55 | If you're using futures you can use `flatMapThrowing`: 56 | 57 | ```swift 58 | return req.client.get("https://httpbin.org/json").flatMapThrowing { res in 59 | try res.content.decode(MyJSONResponse.self) 60 | }.flatMap { json in 61 | // Use JSON here 62 | } 63 | ``` 64 | 65 | ## Configuration 66 | 67 | You can configure the underlying HTTP client via the application. 68 | 69 | ```swift 70 | // Disable automatic redirect following. 71 | app.http.client.configuration.redirectConfiguration = .disallow 72 | ``` 73 | 74 | Note that you must configure the default client _before_ using it for the first time. 75 | 76 | 77 | -------------------------------------------------------------------------------- /docs/basics/client.nl.md: -------------------------------------------------------------------------------- 1 | # Client 2 | 3 | Met Vapor's client API kunt u HTTP-oproepen doen naar externe bronnen. Het is gebouwd op [async-http-client](https://github.com/swift-server/async-http-client) en integreert met de [content](./content.md) API. 4 | 5 | ## Overzicht 6 | 7 | Je kunt toegang krijgen tot de standaard client via `Application` of in een route handler via `Request`. 8 | 9 | ```swift 10 | app.client // Client 11 | 12 | app.get("test") { req in 13 | req.client // Client 14 | } 15 | ``` 16 | 17 | De client van de applicatie is handig voor het maken van HTTP verzoeken tijdens configuratietijd. Als je HTTP verzoeken doet in een route handler, gebruik dan altijd de client van het verzoek. 18 | 19 | ### Methodes 20 | 21 | Om een `GET` verzoek te doen, geef de gewenste URL door aan de `get` convenience methode. 22 | 23 | ```swift 24 | let response = try await req.client.get("https://httpbin.org/status/200") 25 | ``` 26 | 27 | Er zijn methoden voor elk van de HTTP methodes zoals `get`, `post`, en `delete`. Het antwoord van de client wordt teruggestuurd als een future en bevat de HTTP status, headers, en body. 28 | 29 | ### Content 30 | 31 | Vapor's [content](./content.md) API is beschikbaar voor het verwerken van gegevens in client verzoeken en antwoorden. Om inhoud of query parameters te coderen of headers toe te voegen aan het verzoek, gebruik de `beforeSend` closure. 32 | 33 | ```swift 34 | let response = try await req.client.post("https://httpbin.org/status/200") { req in 35 | // Encodeer de querystring naar de URL van het verzoek. 36 | try req.query.encode(["q": "test"]) 37 | 38 | // Encodeer JSON naar de request body. 39 | try req.content.encode(["hello": "world"]) 40 | 41 | // Voeg de auth header toe aan het verzoek. 42 | let auth = BasicAuthorization(username: "something", password: "somethingelse") 43 | req.headers.basicAuthorization = auth 44 | } 45 | // Behandel het antwoord. 46 | ``` 47 | 48 | Je kunt ook de response body decoderen met `Content` op een vergelijkbare manier: 49 | 50 | ```swift 51 | let response = try await req.client.get("https://httpbin.org/json") 52 | let json = try response.content.decode(MyJSONResponse.self) 53 | ``` 54 | 55 | Als je futures gebruikt, kun je `flatMapThrowing` gebruiken: 56 | 57 | ```swift 58 | return req.client.get("https://httpbin.org/json").flatMapThrowing { res in 59 | try res.content.decode(MyJSONResponse.self) 60 | }.flatMap { json in 61 | // Gebruik JSON hier 62 | } 63 | ``` 64 | 65 | ## Configuratie 66 | 67 | U kunt de onderliggende HTTP-client configureren via de applicatie. 68 | 69 | ```swift 70 | // Automatische doorverwijzing uitschakelen. 71 | app.http.client.configuration.redirectConfiguration = .disallow 72 | ``` 73 | 74 | Merk op dat je de standaardclient moet configureren _voordat_ je hem voor het eerst gebruikt. 75 | -------------------------------------------------------------------------------- /docs/basics/client.zh.md: -------------------------------------------------------------------------------- 1 | # Client 2 | 3 | Vapor 的 client API 允许你使用 HTTP 调用外部资源,它基于 [async-http-client](https://github.com/swift-server/async-http-client) 构建,并集成了 [Content](content.zh.md) API。 4 | 5 | 6 | ## 概述 7 | 8 | 你可以通过 `Application` 或通过 `Request` 在路由处理回调中访问默认 `Client`。 9 | 10 | ```swift 11 | app.client // Client 12 | 13 | app.get("test") { req in 14 | req.client // Client 15 | } 16 | ``` 17 | 18 | 19 | `Application` 的 `client` 对于在配置期间发起 HTTP 请求非常有用,如果要在路由处理程序中发起 HTTP 请求,请使用 `req.client`。 20 | 21 | 22 | ### 方法 23 | 24 | 如果你要发起一个 GET 请求,请将所需的 URL 地址传给 `client` 的 `get` 方法,如下所示: 25 | 26 | ```swift 27 | let response = try await req.client.get("https://httpbin.org/status/200") 28 | ``` 29 | 30 | HTTP 的常用方法(例如 `get`, `post`, `delete`)都有便捷的调用方式,Client 的响应会以一个 future 的形式返回,它包含了 HTTP 返回的状态、头部信息和内容。 31 | 32 | 33 | ### Content 34 | 35 | Vapor 的 [Content](content.md) API 可用于处理客户请求和响应中的数据,如果要在请求体中添加参数或编码,请在 `beforeSend` 闭包中进行。 36 | 37 | ```swift 38 | let response = try await req.client.post("https://httpbin.org/status/200") { req in 39 | // 请求 URL 中编码查询字符串。 40 | try req.query.encode(["q": "test"]) 41 | 42 | // 使用 JSON 编码请求体。 43 | try req.content.encode(["hello": "world"]) 44 | 45 | // 在请求头中添加认证头。 46 | let auth = BasicAuthorization(username: "something", password: "somethingelse") 47 | req.headers.basicAuthorization = auth 48 | } 49 | // 处理响应。 50 | ``` 51 | 52 | 你可以用 `Content` 对 response body 解码采用熟悉的方式: 53 | ```swift 54 | let response = try await req.client.get("https://httpbin.org/json") 55 | let json = try response.content.decode(MyJSONResponse.self) 56 | ``` 57 | 58 | 如果要解码响应的数据,请在 `flatMapThrowing` 回调中处理。 59 | 60 | ```swift 61 | req.client.get("https://httpbin.org/json").flatMapThrowing { res in 62 | try res.content.decode(MyJSONResponse.self) 63 | }.map { json in 64 | // 处理返回的JSON信息 65 | } 66 | ``` 67 | 68 | ## 配置 69 | 70 | 你可以通过 `application` 来配置 HTTP `client` 的基础参数。 71 | 72 | ```swift 73 | // 禁止自动跳转 74 | app.http.client.configuration.redirectConfiguration = .disallow 75 | ``` 76 | 77 | 请注意,你必须在首次使用默认的 `client` 之前对其进行配置。 78 | 79 | -------------------------------------------------------------------------------- /docs/basics/controllers.de.md: -------------------------------------------------------------------------------- 1 | # Controller 2 | 3 | Mit Controller können wir unseren Code sinnvoll aufteilen und in unserem Projekt für Ordnung sorgen. Ein Controller kann eine oder mehrere Methoden beinhalten, die Serveranfragen entgegennehmen, verarbeiten und ein entsprechendes Ergebnis zurückliefern. Das folgende Beispiel zeigt einen möglichen Aufbau eines solchen Controllers: 4 | 5 | ```swift 6 | // [TodosController.swift] 7 | 8 | import Vapor 9 | 10 | struct TodosController: RouteCollection { 11 | func boot(routes: RoutesBuilder) throws { 12 | let todos = routes.grouped("todos") 13 | todos.get(use: index) 14 | todos.post(use: create) 15 | 16 | todos.group(":id") { todo in 17 | todo.get(use: show) 18 | todo.put(use: update) 19 | todo.delete(use: delete) 20 | } 21 | } 22 | 23 | func index(req: Request) async throws -> [Todo] { 24 | try await Todo.query(on: req.db).all() 25 | } 26 | 27 | func create(req: Request) async throws -> Todo { 28 | let todo = try req.content.decode(Todo.self) 29 | try await todo.save(on: req.db) 30 | return todo 31 | } 32 | 33 | func show(req: Request) async throws -> Todo { 34 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 35 | throw Abort(.notFound) 36 | } 37 | return todo 38 | } 39 | 40 | func update(req: Request) async throws -> Todo { 41 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 42 | throw Abort(.notFound) 43 | } 44 | let updatedTodo = try req.content.decode(Todo.self) 45 | todo.title = updatedTodo.title 46 | try await todo.save(on: req.db) 47 | return todo 48 | } 49 | 50 | func delete(req: Request) async throws -> HTTPStatus { 51 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 52 | throw Abort(.notFound) 53 | } 54 | try await todo.delete(on: req.db) 55 | return .ok 56 | } 57 | } 58 | ``` 59 | 60 | Die erwähnten Methoden sollten immer ein Objekt vom Typ _Request_ annehmen und ein Wert von Typ _ResponseEncodable_ zurückgegeben. Dabei kann die Methode sowohl asynchron, als auch synchron ausgeführt werden. 61 | 62 | Zum Schluss müssen wir der Anwendung unseren Controller bekannt machen. Hierzu wird der Controller mit Hilfe der Methode _register(:_)_ an das Objekt _app_ übergeben. 63 | 64 | ```swift 65 | // [routes.swift] 66 | 67 | try app.register(collection: TodosController()) 68 | ``` 69 | -------------------------------------------------------------------------------- /docs/basics/controllers.es.md: -------------------------------------------------------------------------------- 1 | # Controladores 2 | 3 | Los controladores son una gran manera de organizar tu código. Son colecciones de métodos que aceptan una petición (request) y devuleven una respuesta (response). 4 | 5 | Un buen sitio donde ubicar tus controladores sería en la carpeta [Controllers](../getting-started/folder-structure.es.md#controllers). 6 | 7 | ## Descripción 8 | 9 | Veamos un controlador de ejemplo. 10 | 11 | ```swift 12 | import Vapor 13 | 14 | struct TodosController: RouteCollection { 15 | func boot(routes: RoutesBuilder) throws { 16 | let todos = routes.grouped("todos") 17 | todos.get(use: index) 18 | todos.post(use: create) 19 | 20 | todos.group(":id") { todo in 21 | todo.get(use: show) 22 | todo.put(use: update) 23 | todo.delete(use: delete) 24 | } 25 | } 26 | 27 | func index(req: Request) async throws -> [Todo] { 28 | try await Todo.query(on: req.db).all() 29 | } 30 | 31 | func create(req: Request) async throws -> Todo { 32 | let todo = try req.content.decode(Todo.self) 33 | try await todo.save(on: req.db) 34 | return todo 35 | } 36 | 37 | func show(req: Request) async throws -> Todo { 38 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 39 | throw Abort(.notFound) 40 | } 41 | return todo 42 | } 43 | 44 | func update(req: Request) async throws -> Todo { 45 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 46 | throw Abort(.notFound) 47 | } 48 | let updatedTodo = try req.content.decode(Todo.self) 49 | todo.title = updatedTodo.title 50 | try await todo.save(on: req.db) 51 | return todo 52 | } 53 | 54 | func delete(req: Request) async throws -> HTTPStatus { 55 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 56 | throw Abort(.notFound) 57 | } 58 | try await todo.delete(on: req.db) 59 | return .ok 60 | } 61 | } 62 | ``` 63 | 64 | Los métodos de un controlador deben aceptar siempre una `Request` (petición) y devolver algo `ResponseEncodable`. Este método puede ser síncrono o asíncrono. 65 | 66 | Finalmente necesitas registrar el controlador en `routes.swift`: 67 | 68 | ```swift 69 | try app.register(collection: TodosController()) 70 | ``` 71 | -------------------------------------------------------------------------------- /docs/basics/controllers.it.md: -------------------------------------------------------------------------------- 1 | # Controller 2 | 3 | I controller sono un ottimo modo per organizzare il codice. Sono collezioni di metodi che prendono una richiesta e ritornano una risposta, e sono a tutti gli effetti gli endpoint dell'applicazione. 4 | 5 | Il luogo migliore in cui mettere i controller è nella loro [cartella](../getting-started/folder-structure.it.md#controllers). 6 | 7 | ## Panoramica 8 | 9 | Diamo un'occhiata ad un esempio di controller. 10 | 11 | ```swift 12 | import Vapor 13 | 14 | struct TodosController: RouteCollection { 15 | func boot(routes: RoutesBuilder) throws { 16 | let todos = routes.grouped("todos") 17 | todos.get(use: index) 18 | todos.post(use: create) 19 | 20 | todos.group(":id") { todo in 21 | todo.get(use: show) 22 | todo.put(use: update) 23 | todo.delete(use: delete) 24 | } 25 | } 26 | 27 | func index(req: Request) async throws -> [Todo] { 28 | try await Todo.query(on: req.db).all() 29 | } 30 | 31 | func create(req: Request) async throws -> Todo { 32 | let todo = try req.content.decode(Todo.self) 33 | try await todo.save(on: req.db) 34 | return todo 35 | } 36 | 37 | func show(req: Request) async throws -> Todo { 38 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 39 | throw Abort(.notFound) 40 | } 41 | return todo 42 | } 43 | 44 | func update(req: Request) async throws -> Todo { 45 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 46 | throw Abort(.notFound) 47 | } 48 | let updatedTodo = try req.content.decode(Todo.self) 49 | todo.title = updatedTodo.title 50 | try await todo.save(on: req.db) 51 | return todo 52 | } 53 | 54 | func delete(req: Request) async throws -> HTTPStatus { 55 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 56 | throw Abort(.notFound) 57 | } 58 | try await todo.delete(on: req.db) 59 | return .ok 60 | } 61 | } 62 | ``` 63 | 64 | I metodi dei controller prendono sempre in input una `Request` e ritornano un qualsiasi `ResponseEncodable`. Tali metodi possono essere asincroni o sincroni. 65 | 66 | Infine, il controller viene registrato nel `routes.swift`: 67 | 68 | ```swift 69 | try app.register(collection: TodosController()) 70 | ``` 71 | -------------------------------------------------------------------------------- /docs/basics/controllers.ja.md: -------------------------------------------------------------------------------- 1 | # コントローラー {#controllers} 2 | 3 | コントローラーはコードを整理するのに適した方法です。これらは、リクエストを受けてレスポンスを返すメソッドの集まりです。 4 | 5 | コントローラーを置く良い場所は、[Controllers](../getting-started/folder-structure.ja.md#controllers) フォルダーです。 6 | 7 | ## 概要 {#overview} 8 | 9 | 例としてコントローラーを見てみましょう。 10 | 11 | ```swift 12 | import Vapor 13 | 14 | struct TodosController: RouteCollection { 15 | func boot(routes: RoutesBuilder) throws { 16 | let todos = routes.grouped("todos") 17 | todos.get(use: index) 18 | todos.post(use: create) 19 | 20 | todos.group(":id") { todo in 21 | todo.get(use: show) 22 | todo.put(use: update) 23 | todo.delete(use: delete) 24 | } 25 | } 26 | 27 | func index(req: Request) async throws -> [Todo] { 28 | try await Todo.query(on: req.db).all() 29 | } 30 | 31 | func create(req: Request) async throws -> Todo { 32 | let todo = try req.content.decode(Todo.self) 33 | try await todo.save(on: req.db) 34 | return todo 35 | } 36 | 37 | func show(req: Request) async throws -> Todo { 38 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 39 | throw Abort(.notFound) 40 | } 41 | return todo 42 | } 43 | 44 | func update(req: Request) async throws -> Todo { 45 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 46 | throw Abort(.notFound) 47 | } 48 | let updatedTodo = try req.content.decode(Todo.self) 49 | todo.title = updatedTodo.title 50 | try await todo.save(on: req.db) 51 | return todo 52 | } 53 | 54 | func delete(req: Request) async throws -> HTTPStatus { 55 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 56 | throw Abort(.notFound) 57 | } 58 | try await todo.delete(on: req.db) 59 | return .ok 60 | } 61 | } 62 | ``` 63 | 64 | コントローラーのメソッドは常に `Request` を受け取り、何か `ResponseEncodable` を返す必要があります。このメソッドは非同期でも同期でも構いません。 65 | 66 | 最後に、コントローラーを `routes.swift` に登録する必要があります: 67 | 68 | ```swift 69 | try app.register(collection: TodosController()) 70 | ``` 71 | -------------------------------------------------------------------------------- /docs/basics/controllers.md: -------------------------------------------------------------------------------- 1 | # Controllers 2 | 3 | Controllers are a great way to organize your code. They are collections of methods that accept a request and return a response. 4 | 5 | A good place to put your controllers is in the [Controllers](../getting-started/folder-structure.md#controllers) folder. 6 | 7 | ## Overview 8 | 9 | Let's take a look at an example controller. 10 | 11 | ```swift 12 | import Vapor 13 | 14 | struct TodosController: RouteCollection { 15 | func boot(routes: RoutesBuilder) throws { 16 | let todos = routes.grouped("todos") 17 | todos.get(use: index) 18 | todos.post(use: create) 19 | 20 | todos.group(":id") { todo in 21 | todo.get(use: show) 22 | todo.put(use: update) 23 | todo.delete(use: delete) 24 | } 25 | } 26 | 27 | func index(req: Request) async throws -> [Todo] { 28 | try await Todo.query(on: req.db).all() 29 | } 30 | 31 | func create(req: Request) async throws -> Todo { 32 | let todo = try req.content.decode(Todo.self) 33 | try await todo.save(on: req.db) 34 | return todo 35 | } 36 | 37 | func show(req: Request) async throws -> Todo { 38 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 39 | throw Abort(.notFound) 40 | } 41 | return todo 42 | } 43 | 44 | func update(req: Request) async throws -> Todo { 45 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 46 | throw Abort(.notFound) 47 | } 48 | let updatedTodo = try req.content.decode(Todo.self) 49 | todo.title = updatedTodo.title 50 | try await todo.save(on: req.db) 51 | return todo 52 | } 53 | 54 | func delete(req: Request) async throws -> HTTPStatus { 55 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 56 | throw Abort(.notFound) 57 | } 58 | try await todo.delete(on: req.db) 59 | return .ok 60 | } 61 | } 62 | ``` 63 | 64 | Controller methods should always accept a `Request` and return something `ResponseEncodable`. This method can be asynchronous or synchronous. 65 | 66 | 67 | Finally you need to register the controller in `routes.swift`: 68 | 69 | ```swift 70 | try app.register(collection: TodosController()) 71 | ``` 72 | -------------------------------------------------------------------------------- /docs/basics/controllers.nl.md: -------------------------------------------------------------------------------- 1 | # Controllers 2 | 3 | Controllers zijn een goede manier om je code te organiseren. Het zijn verzamelingen van methodes die een verzoek accepteren en een antwoord teruggeven. 4 | 5 | Een goede plaats om je controllers te plaatsen is in de [Controllers](../getting-started/folder-structure.md#controllers) map. 6 | 7 | ## Overzicht 8 | 9 | Laten we eens kijken naar een voorbeeldcontroller. 10 | 11 | ```swift 12 | import Vapor 13 | 14 | struct TodosController: RouteCollection { 15 | func boot(routes: RoutesBuilder) throws { 16 | let todos = routes.grouped("todos") 17 | todos.get(use: index) 18 | todos.post(use: create) 19 | 20 | todos.group(":id") { todo in 21 | todo.get(use: show) 22 | todo.put(use: update) 23 | todo.delete(use: delete) 24 | } 25 | } 26 | 27 | func index(req: Request) async throws -> String { 28 | // ... 29 | } 30 | 31 | func create(req: Request) throws -> EventLoopFuture { 32 | // ... 33 | } 34 | 35 | func show(req: Request) throws -> String { 36 | guard let id = req.parameters.get("id") else { 37 | throw Abort(.internalServerError) 38 | } 39 | // ... 40 | } 41 | 42 | func update(req: Request) throws -> String { 43 | guard let id = req.parameters.get("id") else { 44 | throw Abort(.internalServerError) 45 | } 46 | // ... 47 | } 48 | 49 | func delete(req: Request) throws -> String { 50 | guard let id = req.parameters.get("id") else { 51 | throw Abort(.internalServerError) 52 | } 53 | // ... 54 | } 55 | } 56 | ``` 57 | 58 | Controller methodes moeten altijd een `Request` accepteren en iets `ResponseEncodable` teruggeven. Deze methode kan asynchroon of synchroon zijn (of een `EventLoopFuture` teruggeven). 59 | 60 | !!! opmerking 61 | [EventLoopFuture](async.md) waarvan de verwachting `ResponseEncodable` is (d.w.z. `EventLoopFuture`) is ook `ResponseEncodable`. 62 | 63 | Tenslotte moet je de controller registreren in `routes.swift`: 64 | 65 | ```swift 66 | try app.register(collection: TodosController()) 67 | ``` 68 | -------------------------------------------------------------------------------- /docs/basics/controllers.zh.md: -------------------------------------------------------------------------------- 1 | # Controllers 2 | 3 | `Controller` 是将应用程序的不同逻辑进行分组的优秀方案,大多数 Controller 都具备接受多种请求的功能,并根据需要进行响应。 4 | 5 | 建议将其放在 [Controllers](../getting-started/folder-structure.md#controllers) 文件夹下,具体情况可以根据需求划分模块。 6 | 7 | 8 | ## 概述 9 | 10 | 让我们看一个示例 Controller: 11 | 12 | ```swift 13 | import Vapor 14 | 15 | struct TodosController: RouteCollection { 16 | func boot(routes: RoutesBuilder) throws { 17 | let todos = routes.grouped("todos") 18 | todos.get(use: index) 19 | todos.post(use: create) 20 | 21 | todos.group(":id") { todo in 22 | todo.get(use: show) 23 | todo.put(use: update) 24 | todo.delete(use: delete) 25 | } 26 | } 27 | 28 | func index(req: Request) async throws -> [Todo] { 29 | try await Todo.query(on: req.db).all() 30 | } 31 | 32 | func create(req: Request) async throws -> Todo { 33 | let todo = try req.content.decode(Todo.self) 34 | try await todo.save(on: req.db) 35 | return todo 36 | } 37 | 38 | func show(req: Request) async throws -> Todo { 39 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 40 | throw Abort(.notFound) 41 | } 42 | return todo 43 | } 44 | 45 | func update(req: Request) async throws -> Todo { 46 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 47 | throw Abort(.notFound) 48 | } 49 | let updatedTodo = try req.content.decode(Todo.self) 50 | todo.title = updatedTodo.title 51 | try await todo.save(on: req.db) 52 | return todo 53 | } 54 | 55 | func delete(req: Request) async throws -> HTTPStatus { 56 | guard let todo = try await Todo.find(req.parameters.get("id"), on: req.db) else { 57 | throw Abort(.notFound) 58 | } 59 | try await todo.delete(on: req.db) 60 | return .ok 61 | } 62 | } 63 | ``` 64 | 65 | `Controller` 的方法接受 `Request` 参数,并返回 `ResponseEncodable` 对象。该方法可以是异步或者同步。 66 | 67 | 最后,你需要在 `routes.swift` 中注册 Controller: 68 | 69 | ```swift 70 | try app.register(collection: TodosController()) 71 | ``` 72 | -------------------------------------------------------------------------------- /docs/basics/logging.zh.md: -------------------------------------------------------------------------------- 1 | # Logging 2 | 3 | Vapor 的 `Logging` API 是基于 Apple 的 [SwiftLog](https://github.com/apple/swift-log) 而构建。意味着 Vapor 兼容所有基于 `SwiftLog` 实现的[后端框架](https://github.com/apple/swift-log#backends)。 4 | 5 | ## Logger 6 | 7 | `Logger` 的实例用于输出日志消息,Vapor 提供了一些便捷的方法使用日志记录器。 8 | 9 | ### Request 10 | 11 | 每个传入 `Request` 都有一个单独的日志记录器,你可以在该请求中使用任何类型日志。 12 | 13 | ```swift 14 | app.get("hello") { req -> String in 15 | req.logger.info("Hello, logs!") 16 | return "Hello, world!" 17 | } 18 | ``` 19 | 20 | 请求的日志记录器都有一个单独的`UUID`用于标识该请求,便于追踪该日志。 21 | 22 | ``` 23 | [ INFO ] Hello, logs! [request-id: C637065A-8CB0-4502-91DC-9B8615C5D315] (App/routes.swift:10) 24 | ``` 25 | 26 | !!! info "信息" 27 | 日志记录器的元数据仅在调试日志级别或者更低级别显示。 28 | 29 | 30 | ### 应用 31 | 32 | 关于应用程序启动和配置过程中的日志消息,可以使用 `Application` 的日志记录器: 33 | 34 | ```swift 35 | app.logger.info("Setting up migrations...") 36 | app.migrations.use(...) 37 | ``` 38 | 39 | ### 自定义日志记录器 40 | 41 | 在无法访问 `Application` 或者 `Request` 情况下,你可以初始化一个新的 `Logger`。 42 | 43 | ```swift 44 | let logger = Logger(label: "dev.logger.my") 45 | logger.info(...) 46 | ``` 47 | 48 | 尽管自定义的日志记录器仍将输出你配置的后端日志记录,但是他们没有附带重要的元数据,比如 `request` 的 `UUID`。所以尽量使用 `application` 或者 `request` 的日志记录器。 49 | 50 | ## 日志级别(Level) 51 | 52 | `SwiftLog` 支持多种日志级别。 53 | 54 | 55 | |名称|说明| 56 | |-|-| 57 | |trace|用户级基本输出信息| 58 | |debug|用户级调试信息| 59 | |info|用户级重要信息| 60 | |notice|表明会出现非错误的情形,需要关注处理| 61 | |warning|表明会出现潜在错误的情形,比 `notice` 的消息严重| 62 | |error|指出发生错误事件,但不影响系统的继续运行| 63 | |critical|系统级危险,需要立即关注错误信息并处理| 64 | 65 | 出现 `critical` 消息时,日志框架可以自由的执行权限更重的操作来捕获系统状态(比如捕获跟踪堆栈)以方便调试。 66 | 67 | 默认情况下,Vapor 使用 `info` 级别日志。当运行在 `production` 环境时,将使用 `notice` 提高性能。 68 | 69 | ### 修改日志级别 70 | 71 | 不管环境模式如何,你都可以通过修改日志级别来增加或减少生成的日志数量。 72 | 73 | 第一种方法,在启动应用程序时传递可选参数 `--log` 标志: 74 | 75 | ```sh 76 | swift run App serve --log debug 77 | ``` 78 | 79 | 第二种方法,通过设置 `LOG_LEVEL` 环境变量: 80 | 81 | ```sh 82 | export LOG_LEVEL=debug 83 | swift run App serve 84 | ``` 85 | 86 | 这两种方法可以在 Xcode 中编辑 `App`(scheme)模式进行修改。 87 | 88 | ## 配置 89 | 90 | SwiftLog 可以通过每次进程启动 `LoggingSystem` 时进行配置。Vapor 项目通常在 `entrypoint.swift` 执行操作。 91 | 92 | ```swift 93 | var env = try Environment.detect() 94 | try LoggingSystem.bootstrap(from: &env) 95 | ``` 96 | 97 | `bootstrap(from:)` 是 Vapor 提供的调用方法,它将基于命令行参数和环境变量来配置默认日志处理操作。默认的日志处理操作支持使用 ANSI 颜色将消息输出到终端。 98 | 99 | ### 自定义操作 100 | 101 | 你可以覆盖 Vapor 的默认日志处理并注册自己的日志处理操作。 102 | 103 | ```swift 104 | import Logging 105 | 106 | LoggingSystem.bootstrap { label in 107 | StreamLogHandler.standardOutput(label: label) 108 | } 109 | ``` 110 | 111 | 所有 SwiftLog 支持的后端框架均可与 Vapor 一起工作。但是,使用命令行参数和环境变量更改日志级别只支持 Vapor 的默认日志处理操作。 112 | -------------------------------------------------------------------------------- /docs/deploy/supervisor.es.md: -------------------------------------------------------------------------------- 1 | # Supervisor 2 | 3 | [Supervisor](http://supervisord.org) es un sistema de control de procesos que facilita iniciar, parar y reiniciar tu aplicación de Vapor. 4 | 5 | ## Instalación 6 | 7 | Supervisor puede instalarse en Linux mediante los manejadores de paquetes. 8 | 9 | ### Ubuntu 10 | 11 | ```sh 12 | sudo apt-get update 13 | sudo apt-get install supervisor 14 | ``` 15 | 16 | ### CentOS y Amazon Linux 17 | 18 | ```sh 19 | sudo yum install supervisor 20 | ``` 21 | 22 | ### Fedora 23 | 24 | ```sh 25 | sudo dnf install supervisor 26 | ``` 27 | 28 | ## Configuración 29 | 30 | Cada aplicación de Vapor en tu servidor debería tener su propio fichero de configuración. Para un proyecto `Hello` de ejemplo, el fichero de configuración estaría localizado en `/etc/supervisor/conf.d/hello.conf` 31 | 32 | ```sh 33 | [program:hello] 34 | command=/home/vapor/hello/.build/release/App serve --env production 35 | directory=/home/vapor/hello/ 36 | user=vapor 37 | stdout_logfile=/var/log/supervisor/%(program_name)-stdout.log 38 | stderr_logfile=/var/log/supervisor/%(program_name)-stderr.log 39 | ``` 40 | 41 | Tal y como hemos especificado en nuestro fichero de configuración, el proyecto `Hello` se encuentra en la carpeta "home" del usuario `vapor`. Asegúrate de que `directory` apunta al directorio raíz de tu proyecto, donde está el fichero `Package.swift`. 42 | 43 | La marca (flag) `--env production` deshabilitará el registro detallado. 44 | 45 | ### Entorno 46 | 47 | Puedes exportar variables a tu aplicación de Vapor con Supervisor. Para exportar varios valores de entorno, ponlos todos en una línea. Según [Supervisor documentation](http://supervisord.org/configuration.html#program-x-section-values): 48 | 49 | > Los valores que contengan caracteres no alfanuméricos deberán ir entrecomillados (p.ej. KEY="val:123",KEY2="val,456"). De lo contrario, entrecomillar los valores es opcional pero recomendado. 50 | 51 | ```sh 52 | environment=PORT=8123,ANOTHERVALUE="/something/else" 53 | ``` 54 | 55 | Las variables exportadas pueden usarse en Vapor mediante `Environment.get` 56 | 57 | ```swift 58 | let port = Environment.get("PORT") 59 | ``` 60 | 61 | ## Inicio 62 | 63 | Ahora ya puedes cargar e iniciar tu aplicación. 64 | 65 | ```sh 66 | supervisorctl reread 67 | supervisorctl add hello 68 | supervisorctl start hello 69 | ``` 70 | 71 | !!! note "Nota" 72 | El comando `add` puede haber iniciado ya tu aplicación. 73 | -------------------------------------------------------------------------------- /docs/deploy/supervisor.ja.md: -------------------------------------------------------------------------------- 1 | # Supervisor 2 | 3 | [Supervisor](http://supervisord.org)は、Vaporアプリの起動、停止、再起動を簡単に行えるプロセス制御システムです。 4 | 5 | ## インストール {#install} 6 | 7 | SupervisorはLinuxのパッケージマネージャーからインストールできます。 8 | 9 | ### Ubuntu 10 | 11 | ```sh 12 | sudo apt-get update 13 | sudo apt-get install supervisor 14 | ``` 15 | 16 | ### CentOSとAmazon Linux {#centos-and-amazon-linux} 17 | 18 | ```sh 19 | sudo yum install supervisor 20 | ``` 21 | 22 | ### Fedora 23 | 24 | ```sh 25 | sudo dnf install supervisor 26 | ``` 27 | 28 | ## 設定 {#configure} 29 | 30 | サーバー上の各Vaporアプリには独自の設定ファイルが必要です。例として`Hello`プロジェクトの場合、設定ファイルは`/etc/supervisor/conf.d/hello.conf`に配置されます。 31 | 32 | ```sh 33 | [program:hello] 34 | command=/home/vapor/hello/.build/release/App serve --env production 35 | directory=/home/vapor/hello/ 36 | user=vapor 37 | stdout_logfile=/var/log/supervisor/%(program_name)s-stdout.log 38 | stderr_logfile=/var/log/supervisor/%(program_name)s-stderr.log 39 | ``` 40 | 41 | 設定ファイルで指定されているように、`Hello`プロジェクトはユーザー`vapor`のホームフォルダに配置されています。`directory`が`Package.swift`ファイルのあるプロジェクトのルートディレクトリを指していることを確認してください。 42 | 43 | `--env production`フラグは冗長なログを無効にします。 44 | 45 | ### 環境変数 {#environment} 46 | 47 | supervisorを使ってVaporアプリに変数をエクスポートできます。複数の環境値をエクスポートする場合は、すべて1行に記述します。[Supervisorドキュメント](http://supervisord.org/configuration.html#program-x-section-values)によると: 48 | 49 | > 英数字以外の文字を含む値は引用符で囲む必要があります(例:KEY="val:123",KEY2="val,456")。それ以外の場合、値を引用符で囲むことは任意ですが推奨されます。 50 | 51 | ```sh 52 | environment=PORT=8123,ANOTHERVALUE="/something/else" 53 | ``` 54 | 55 | エクスポートされた変数は、Vaporで`Environment.get`を使用して利用できます。 56 | 57 | ```swift 58 | let port = Environment.get("PORT") 59 | ``` 60 | 61 | ## 起動 {#start} 62 | 63 | これでアプリをロードして起動できます。 64 | 65 | ```sh 66 | supervisorctl reread 67 | supervisorctl add hello 68 | supervisorctl start hello 69 | ``` 70 | 71 | !!! note 72 | `add`コマンドはすでにアプリを起動している可能性があります。 -------------------------------------------------------------------------------- /docs/deploy/supervisor.md: -------------------------------------------------------------------------------- 1 | # Supervisor 2 | 3 | [Supervisor](http://supervisord.org) is a process control system that makes it easy to start, stop, and restart your Vapor app. 4 | 5 | ## Install 6 | 7 | Supervisor can be installed through package managers on Linux. 8 | 9 | ### Ubuntu 10 | 11 | ```sh 12 | sudo apt-get update 13 | sudo apt-get install supervisor 14 | ``` 15 | 16 | ### CentOS and Amazon Linux 17 | 18 | ```sh 19 | sudo yum install supervisor 20 | ``` 21 | 22 | ### Fedora 23 | 24 | ```sh 25 | sudo dnf install supervisor 26 | ``` 27 | 28 | ## Configure 29 | 30 | Each Vapor app on your server should have its own configuration file. For an example `Hello` project, the configuration file would be located at `/etc/supervisor/conf.d/hello.conf` 31 | 32 | ```sh 33 | [program:hello] 34 | command=/home/vapor/hello/.build/release/App serve --env production 35 | directory=/home/vapor/hello/ 36 | user=vapor 37 | stdout_logfile=/var/log/supervisor/%(program_name)s-stdout.log 38 | stderr_logfile=/var/log/supervisor/%(program_name)s-stderr.log 39 | ``` 40 | 41 | As specified in our configuration file the `Hello` project is located in the home folder for the user `vapor`. Make sure `directory` points to the root directory of your project where the `Package.swift` file is. 42 | 43 | The `--env production` flag will disable verbose logging. 44 | 45 | ### Environment 46 | 47 | You can export variables to your Vapor app with supervisor. For exporting multiple environment values, put them all on one line. Per [Supervisor documentation](http://supervisord.org/configuration.html#program-x-section-values): 48 | 49 | > Values containing non-alphanumeric characters should be quoted (e.g. KEY="val:123",KEY2="val,456"). Otherwise, quoting the values is optional but recommended. 50 | 51 | ```sh 52 | environment=PORT=8123,ANOTHERVALUE="/something/else" 53 | ``` 54 | 55 | Exported variables can be used in Vapor using `Environment.get` 56 | 57 | ```swift 58 | let port = Environment.get("PORT") 59 | ``` 60 | 61 | ## Start 62 | 63 | You can now load and start your app. 64 | 65 | ```sh 66 | supervisorctl reread 67 | supervisorctl add hello 68 | supervisorctl start hello 69 | ``` 70 | 71 | !!! note 72 | The `add` command may have already started your app. 73 | -------------------------------------------------------------------------------- /docs/deploy/supervisor.nl.md: -------------------------------------------------------------------------------- 1 | # Supervisor 2 | 3 | [Supervisor](http://supervisord.org) is een procescontrolesysteem dat het eenvoudig maakt om uw Vapor-app te starten, te stoppen en opnieuw op te starten. 4 | 5 | ## Installeren 6 | 7 | Supervisor kan worden geïnstalleerd via pakketbeheer op Linux. 8 | 9 | ### Ubuntu 10 | 11 | ```sh 12 | sudo apt-get update 13 | sudo apt-get install supervisor 14 | ``` 15 | 16 | ### CentOS and Amazon Linux 17 | 18 | ```sh 19 | sudo yum install supervisor 20 | ``` 21 | 22 | ### Fedora 23 | 24 | ```sh 25 | sudo dnf install supervisor 26 | ``` 27 | 28 | ## Configureren 29 | 30 | Elke Vapor toepassing op uw server zou zijn eigen configuratiebestand moeten hebben. Voor een voorbeeld van een `Hello` project, zou het configuratiebestand te vinden zijn in `/etc/supervisor/conf.d/hello.conf` 31 | 32 | ```sh 33 | [program:hello] 34 | command=/home/vapor/hello/.build/release/App serve --env production 35 | directory=/home/vapor/hello/ 36 | user=vapor 37 | stdout_logfile=/var/log/supervisor/%(program_name)s-stdout.log 38 | stderr_logfile=/var/log/supervisor/%(program_name)s-stderr.log 39 | ``` 40 | 41 | Zoals gespecificeerd in ons configuratie bestand staat het `Hello` project in de thuismap van de gebruiker `vapor`. Zorg ervoor dat `directory` wijst naar de root directory van uw project waar het `Package.swift` bestand staat. 42 | 43 | De `--env production` vlag schakelt verbose logging uit. 44 | 45 | ### Environment 46 | 47 | U kunt variabelen exporteren naar uw Vapor app met supervisor. Voor het exporteren van meerdere omgevingswaarden, zet ze allemaal op één regel. Per [Supervisor documentatie](http://supervisord.org/configuration.html#program-x-section-values): 48 | 49 | > Waarden die niet-alfanumerieke tekens bevatten moeten worden geciteerd (bijv. KEY="val:123",KEY2="val,456"). Anders is het citeren van de waarden optioneel, maar aanbevolen. 50 | 51 | ```sh 52 | environment=PORT=8123,ANOTHERVALUE="/something/else" 53 | ``` 54 | 55 | Geëxporteerde variabelen kunnen in Vapor gebruikt worden met `Environment.get` 56 | 57 | ```swift 58 | let port = Environment.get("PORT") 59 | ``` 60 | 61 | ## Start 62 | 63 | U kunt nu uw app laden en starten. 64 | 65 | ```sh 66 | supervisorctl reread 67 | supervisorctl add hello 68 | supervisorctl start hello 69 | ``` 70 | 71 | !!! note "Opmerking" 72 | Het `add` commando kan uw app al gestart hebben. 73 | -------------------------------------------------------------------------------- /docs/deploy/supervisor.zh.md: -------------------------------------------------------------------------------- 1 | # Supervisor 2 | 3 | [Supervisor](http://supervisord.org) 是一个进程控制系统,可让你轻松启动、停止和重启你的 Vapor 应用程序。 4 | 5 | ## 安装 6 | 7 | Supervisor 可以通过 Linux 上的包管理器安装。 8 | 9 | ### Ubuntu 10 | 11 | ```sh 12 | sudo apt-get update 13 | sudo apt-get install supervisor 14 | ``` 15 | 16 | ### CentOS and Amazon Linux 17 | 18 | ```sh 19 | sudo yum install supervisor 20 | ``` 21 | 22 | ### Fedora 23 | 24 | ```sh 25 | sudo dnf install supervisor 26 | ``` 27 | 28 | ## 配置 29 | 30 | 服务器上的每个 Vapor 应用程序都应该有自己的配置文件。例如 `Hello` 项目,配置文件位于 `/etc/supervisor/conf.d/hello.conf` 31 | 32 | ```sh 33 | [program:hello] 34 | command=/home/vapor/hello/.build/release/App serve --env production 35 | directory=/home/vapor/hello/ 36 | user=vapor 37 | stdout_logfile=/var/log/supervisor/%(program_name)s-stdout.log 38 | stderr_logfile=/var/log/supervisor/%(program_name)s-stderr.log 39 | ``` 40 | 41 | 正如我们的配置文件中所指定的, `Hello` 项目位于用户 `vapor` 的主文件夹中。确保 `directory` 指向 `Package.swift` 文件所在项目的根目录。 42 | 43 | `--env production` 标志会禁用详细日志记录。 44 | 45 | ### 环境 46 | 47 | 你可以使用 supervisor 将变量导出到你的 Vapor 应用程序。要导出多个环境值,请将它们全部放在一行上。根据 [Supervisor 文档](http://supervisord.org/configuration.html#program-x-section-values): 48 | 49 | > 包含非字母数字字符的值应该用引号括起来(e.g. KEY="val:123",KEY2="val,456")。否则,引用值是可选的,但是推荐使用。 50 | 51 | ```sh 52 | environment=PORT=8123,ANOTHERVALUE="/something/else" 53 | ``` 54 | 55 | 可以在 Vapor 中使用 `Environment.get` 导出变量 56 | 57 | ```swift 58 | let port = Environment.get("PORT") 59 | ``` 60 | 61 | ## 开始 62 | 63 | 你现在可以加载并启动你的应用程序。 64 | 65 | ```sh 66 | supervisorctl reread 67 | supervisorctl add hello 68 | supervisorctl start hello 69 | ``` 70 | 71 | !!! note "注意" 72 | `add` 命令可能已经启动了你的应用程序。 73 | -------------------------------------------------------------------------------- /docs/deploy/systemd.es.md: -------------------------------------------------------------------------------- 1 | # Systemd 2 | 3 | Systemd es el gestor de sistema y servicios por defecto en la mayoría de distribuciones de Linux. Normalmente está instalado por defecto, así que no se necesita ninguna instalación en las distribuciones de Swift soportadas. 4 | 5 | ## Configuración 6 | 7 | Cada aplicación Vapor en tu servidor debería tener su propio fichero de servicio. Para un proyecto `Hello` de ejemplo, el fichero de configuración estaría localizado en `/etc/systemd/system/hello.service`. Este fichero debería tener lo siguiente: 8 | 9 | ```sh 10 | [Unit] 11 | Description=Hello 12 | Requires=network.target 13 | After=network.target 14 | 15 | [Service] 16 | Type=simple 17 | User=vapor 18 | Group=vapor 19 | Restart=always 20 | RestartSec=3 21 | WorkingDirectory=/home/vapor/hello 22 | ExecStart=/home/vapor/hello/.build/release/App serve --env production 23 | StandardOutput=syslog 24 | StandardError=syslog 25 | SyslogIdentifier=vapor-hello 26 | 27 | [Install] 28 | WantedBy=multi-user.target 29 | ``` 30 | 31 | Tal y como está especificado en nuestro fichero de configuración, el proyecto `Hello` se encuentra en la carpeta "home" del usuario `vapor`. Asegúrate de que `WorkingDirectory` apunta al directorio raíz de tu proyecto, que es donde el fichero `Package.swift` está. 32 | 33 | La marca (flag) `--env production`deshabilitará el registro detallado. 34 | 35 | ### Entorno 36 | De lo contrario, entrecomillar los valores es opcional pero recomendado. 37 | 38 | Puedes exportar variables de dos maneras via systemd. Puedes crear un fichero de entorno con todas las variables establecidas en él: 39 | 40 | ```sh 41 | EnvironmentFile=/path/to/environment/file1 42 | EnvironmentFile=/path/to/environment/file2 43 | ``` 44 | 45 | 46 | O puedes añadirlas directamente al fichero de servicio bajo `[service]`: 47 | 48 | ```sh 49 | Environment="PORT=8123" 50 | Environment="ANOTHERVALUE=/something/else" 51 | ``` 52 | Las variables exportadas pueden usarse en Vapor mediante `Environment.get` 53 | 54 | ```swift 55 | let port = Environment.get("PORT") 56 | ``` 57 | 58 | ## Inicio 59 | 60 | Ahora ya puedes cargar, habilitar, iniciar y apagar tu aplicación ejecutando lo siguiente como raíz. 61 | 62 | ```sh 63 | systemctl daemon-reload 64 | systemctl enable hello 65 | systemctl start hello 66 | systemctl stop hello 67 | systemctl restart hello 68 | ``` 69 | -------------------------------------------------------------------------------- /docs/deploy/systemd.ja.md: -------------------------------------------------------------------------------- 1 | # Systemd 2 | 3 | Systemdは、ほとんどのLinuxディストリビューションにおけるデフォルトのシステムおよびサービスマネージャーです。通常はデフォルトでインストールされているため、サポートされているSwiftディストリビューションでは追加のインストールは必要ありません。 4 | 5 | ## 設定 {#configure} 6 | 7 | サーバー上の各Vaporアプリには独自のサービスファイルが必要です。例えば`Hello`プロジェクトの場合、設定ファイルは`/etc/systemd/system/hello.service`に配置されます。このファイルは以下のようになります: 8 | 9 | ```sh 10 | [Unit] 11 | Description=Hello 12 | Requires=network.target 13 | After=network.target 14 | 15 | [Service] 16 | Type=simple 17 | User=vapor 18 | Group=vapor 19 | Restart=always 20 | RestartSec=3 21 | WorkingDirectory=/home/vapor/hello 22 | ExecStart=/home/vapor/hello/.build/release/App serve --env production 23 | StandardOutput=syslog 24 | StandardError=syslog 25 | SyslogIdentifier=vapor-hello 26 | 27 | [Install] 28 | WantedBy=multi-user.target 29 | ``` 30 | 31 | 設定ファイルで指定されているように、`Hello`プロジェクトはユーザー`vapor`のホームフォルダーに配置されています。`WorkingDirectory`が`Package.swift`ファイルがあるプロジェクトのルートディレクトリを指していることを確認してください。 32 | 33 | `--env production`フラグは詳細なログ出力を無効にします。 34 | 35 | ### 環境変数 {#environment} 36 | 37 | systemd経由で変数をエクスポートする方法は2つあります。すべての変数が設定された環境ファイルを作成する方法: 38 | 39 | ```sh 40 | EnvironmentFile=/path/to/environment/file1 41 | EnvironmentFile=/path/to/environment/file2 42 | ``` 43 | 44 | または、`[service]`セクションの下のサービスファイルに直接追加する方法: 45 | 46 | ```sh 47 | Environment="PORT=8123" 48 | Environment="ANOTHERVALUE=/something/else" 49 | ``` 50 | エクスポートされた変数は、`Environment.get`を使用してVaporで使用できます 51 | 52 | ```swift 53 | let port = Environment.get("PORT") 54 | ``` 55 | 56 | ## 起動 {#start} 57 | 58 | rootとして以下のコマンドを実行することで、アプリのロード、有効化、開始、停止、再起動ができます。 59 | 60 | ```sh 61 | systemctl daemon-reload 62 | systemctl enable hello 63 | systemctl start hello 64 | systemctl stop hello 65 | systemctl restart hello 66 | ``` -------------------------------------------------------------------------------- /docs/deploy/systemd.md: -------------------------------------------------------------------------------- 1 | # Systemd 2 | 3 | Systemd is the default system and service manager on most Linux distributions. It is usually installed by default so no installation is needed on supported Swift distributions. 4 | 5 | ## Configure 6 | 7 | Each Vapor app on your server should have its own service file. For an example `Hello` project, the configuration file would be located at `/etc/systemd/system/hello.service`. This file should look like the following: 8 | 9 | ```sh 10 | [Unit] 11 | Description=Hello 12 | Requires=network.target 13 | After=network.target 14 | 15 | [Service] 16 | Type=simple 17 | User=vapor 18 | Group=vapor 19 | Restart=always 20 | RestartSec=3 21 | WorkingDirectory=/home/vapor/hello 22 | ExecStart=/home/vapor/hello/.build/release/App serve --env production 23 | StandardOutput=syslog 24 | StandardError=syslog 25 | SyslogIdentifier=vapor-hello 26 | 27 | [Install] 28 | WantedBy=multi-user.target 29 | ``` 30 | 31 | As specified in our configuration file the `Hello` project is located in the home folder for the user `vapor`. Make sure `WorkingDirectory` points to the root directory of your project where the `Package.swift` file is. 32 | 33 | The `--env production` flag will disable verbose logging. 34 | 35 | ### Environment 36 | Otherwise, quoting the values is optional but recommended. 37 | 38 | You can export variables in two ways via systemd. Either by creating an environment file with all the variables set in it: 39 | 40 | ```sh 41 | EnvironmentFile=/path/to/environment/file1 42 | EnvironmentFile=/path/to/environment/file2 43 | ``` 44 | 45 | 46 | Or you can add them directly to the service file under `[service]`: 47 | 48 | ```sh 49 | Environment="PORT=8123" 50 | Environment="ANOTHERVALUE=/something/else" 51 | ``` 52 | Exported variables can be used in Vapor using `Environment.get` 53 | 54 | ```swift 55 | let port = Environment.get("PORT") 56 | ``` 57 | 58 | ## Start 59 | 60 | You can now load, enable, start, stop and restart your app by running the following as root. 61 | 62 | ```sh 63 | systemctl daemon-reload 64 | systemctl enable hello 65 | systemctl start hello 66 | systemctl stop hello 67 | systemctl restart hello 68 | ``` 69 | -------------------------------------------------------------------------------- /docs/deploy/systemd.nl.md: -------------------------------------------------------------------------------- 1 | # Systemd 2 | 3 | Systemd is het standaard systeem en service manager op de meeste Linux distributies. Het wordt meestal standaard geïnstalleerd, zodat geen installatie nodig is op ondersteunde Swift-distributies. 4 | 5 | ## Configureren 6 | 7 | Elke Vapor app op uw server zou zijn eigen service bestand moeten hebben. Voor een voorbeeld `Hello` project, zou het configuratie bestand te vinden zijn in `/etc/systemd/system/hello.service`. Dit bestand zou er als volgt uit moeten zien: 8 | 9 | ```sh 10 | [Unit] 11 | Description=Hello 12 | Requires=network.target 13 | After=network.target 14 | 15 | [Service] 16 | Type=simple 17 | User=vapor 18 | Group=vapor 19 | Restart=always 20 | RestartSec=3 21 | WorkingDirectory=/home/vapor/hello 22 | ExecStart=/home/vapor/hello/.build/release/App serve --env production 23 | StandardOutput=syslog 24 | StandardError=syslog 25 | SyslogIdentifier=vapor-hello 26 | 27 | [Install] 28 | WantedBy=multi-user.target 29 | ``` 30 | 31 | Zoals gespecificeerd in ons configuratie bestand bevindt het `Hello` project zich in de thuismap van de gebruiker `vapor`. Zorg ervoor dat `WorkingDirectory` wijst naar de root directory van uw project waar het `Package.swift` bestand staat. 32 | 33 | De `--env production` vlag schakelt verbose logging uit. 34 | 35 | ### Environment 36 | Anders is het citeren van de waarden optioneel maar aanbevolen. 37 | 38 | Je kunt variabelen op twee manieren exporteren via systemd. Ofwel door een omgevingsbestand aan te maken met alle variabelen erin ingesteld: 39 | 40 | ```sh 41 | EnvironmentFile=/path/to/environment/file1 42 | EnvironmentFile=/path/to/environment/file2 43 | ``` 44 | 45 | 46 | Of u kunt ze direct toevoegen aan het service bestand onder `[service]`: 47 | 48 | ```sh 49 | Environment="PORT=8123" 50 | Environment="ANOTHERVALUE=/something/else" 51 | ``` 52 | Geëxporteerde variabelen kunnen in Vapor gebruikt worden met `Environment.get` 53 | 54 | ```swift 55 | let port = Environment.get("PORT") 56 | ``` 57 | 58 | ## Start 59 | 60 | U kunt nu uw app laden, inschakelen, starten, stoppen en herstarten door het volgende uit te voeren als root. 61 | 62 | ```sh 63 | systemctl daemon-reload 64 | systemctl enable hello 65 | systemctl start hello 66 | systemctl stop hello 67 | systemctl restart hello 68 | ``` 69 | -------------------------------------------------------------------------------- /docs/deploy/systemd.zh.md: -------------------------------------------------------------------------------- 1 | # Systemd 2 | 3 | Systemd 是大多数 Linux 发行版中默认的系统和服务管理器。它通常是默认安装的,所以在支持 Swift 的发行版上无需安装。 4 | 5 | ## 配置 6 | 7 | 服务器上的每个 Vapor 应用程序都应该有自己的服务文件。对于 `Hello` 示例项目,配置文件位于 `/etc/systemd/system/hello.service`. 该文件如下所示: 8 | 9 | ```sh 10 | [Unit] 11 | Description=Hello 12 | Requires=network.target 13 | After=network.target 14 | 15 | [Service] 16 | Type=simple 17 | User=vapor 18 | Group=vapor 19 | Restart=always 20 | RestartSec=3 21 | WorkingDirectory=/home/vapor/hello 22 | ExecStart=/home/vapor/hello/.build/release/App serve --env production 23 | StandardOutput=syslog 24 | StandardError=syslog 25 | SyslogIdentifier=vapor-hello 26 | 27 | [Install] 28 | WantedBy=multi-user.target 29 | ``` 30 | 31 | 正如我们的配置文件中所指定的,`Hello` 项目位于用户 `vapor` 的主文件夹中。确保 `WorkingDirectory` 指向 `Package.swift` 文件所在项目的根目录。 32 | 33 | `--env production` 标志将禁用详细日志记录。 34 | 35 | ### 环境 36 | 37 | 此外,以下部分是可选配置,但建议使用。 38 | 39 | 你可以通过 systemd 以下面其中一种方式导出变量,或通过创建一个包含所有环境变量的文件: 40 | 41 | ```sh 42 | EnvironmentFile=/path/to/environment/file1 43 | EnvironmentFile=/path/to/environment/file2 44 | ``` 45 | 46 | 或者你可以直接将它们添加到服务文件 `[service]` 下: 47 | 48 | ```sh 49 | Environment="PORT=8123" 50 | Environment="ANOTHERVALUE=/something/else" 51 | ``` 52 | 53 | 在 Vapor 中可以用使用 `Environment.get` 导出变量。 54 | 55 | ```swift 56 | let port = Environment.get("PORT") 57 | ``` 58 | 59 | ## 启动 60 | 61 | 你现在可以通过 `root` 身份运行以下命令来加载、启用、启动、停止和重启你的应用程序了。 62 | 63 | ```sh 64 | systemctl daemon-reload 65 | systemctl enable hello 66 | systemctl start hello 67 | systemctl stop hello 68 | systemctl restart hello 69 | ``` 70 | -------------------------------------------------------------------------------- /docs/fluent/migration.ja.md: -------------------------------------------------------------------------------- 1 | # マイグレーション {#migrations} 2 | 3 | マイグレーションは、データベースのバージョン管理システムのようなものです。各マイグレーションは、データベースへの変更とその取り消し方法を定義します。マイグレーションを通じてデータベースを変更することで、時間の経過とともにデータベースを進化させる一貫性のある、テスト可能で、共有可能な方法を作成します。 4 | 5 | ```swift 6 | // マイグレーションの例 7 | struct MyMigration: Migration { 8 | func prepare(on database: any Database) -> EventLoopFuture { 9 | // データベースに変更を加える 10 | } 11 | 12 | func revert(on database: any Database) -> EventLoopFuture { 13 | // `prepare`で行った変更を取り消す(可能な場合) 14 | } 15 | } 16 | ``` 17 | 18 | `async`/`await`を使用している場合は、`AsyncMigration`プロトコルを実装する必要があります: 19 | 20 | ```swift 21 | struct MyMigration: AsyncMigration { 22 | func prepare(on database: any Database) async throws { 23 | // データベースに変更を加える 24 | } 25 | 26 | func revert(on database: any Database) async throws { 27 | // `prepare`で行った変更を取り消す(可能な場合) 28 | } 29 | } 30 | ``` 31 | 32 | `prepare`メソッドは、提供された`Database`に変更を加える場所です。これらは、テーブルやコレクション、フィールド、制約の追加や削除などのデータベーススキーマへの変更である可能性があります。また、新しいモデルインスタンスの作成、フィールド値の更新、クリーンアップなど、データベースの内容を変更することもできます。 33 | 34 | `revert`メソッドは、可能であればこれらの変更を元に戻す場所です。マイグレーションを元に戻せることで、プロトタイピングとテストが容易になります。また、本番環境へのデプロイが計画通りに進まなかった場合のバックアッププランも提供します。 35 | 36 | ## 登録 {#register} 37 | 38 | マイグレーションは`app.migrations`を使用してアプリケーションに登録されます。 39 | 40 | ```swift 41 | import Fluent 42 | import Vapor 43 | 44 | app.migrations.add(MyMigration()) 45 | ``` 46 | 47 | `to`パラメータを使用して特定のデータベースにマイグレーションを追加できます。それ以外の場合は、デフォルトのデータベースが使用されます。 48 | 49 | ```swift 50 | app.migrations.add(MyMigration(), to: .myDatabase) 51 | ``` 52 | 53 | マイグレーションは依存関係の順序でリストする必要があります。例えば、`MigrationB`が`MigrationA`に依存している場合、`app.migrations`に2番目に追加する必要があります。 54 | 55 | ## マイグレート {#migrate} 56 | 57 | データベースをマイグレートするには、`migrate`コマンドを実行します。 58 | 59 | ```sh 60 | swift run App migrate 61 | ``` 62 | 63 | このコマンドは[Xcodeから実行](../advanced/commands.md#xcode)することもできます。migrateコマンドは、最後に実行されてから新しいマイグレーションが登録されているかデータベースをチェックします。新しいマイグレーションがある場合は、実行前に確認を求めます。 64 | 65 | ### リバート {#revert} 66 | 67 | データベースのマイグレーションを元に戻すには、`--revert`フラグを付けて`migrate`を実行します。 68 | 69 | ```sh 70 | swift run App migrate --revert 71 | ``` 72 | 73 | このコマンドは、最後に実行されたマイグレーションのバッチをデータベースでチェックし、それらを元に戻す前に確認を求めます。 74 | 75 | ### 自動マイグレート {#auto-migrate} 76 | 77 | 他のコマンドを実行する前にマイグレーションを自動的に実行したい場合は、`--auto-migrate`フラグを渡すことができます。 78 | 79 | ```sh 80 | swift run App serve --auto-migrate 81 | ``` 82 | 83 | プログラムで実行することもできます。 84 | 85 | ```swift 86 | try app.autoMigrate().wait() 87 | 88 | // または 89 | try await app.autoMigrate() 90 | ``` 91 | 92 | これらのオプションは両方ともリバートにも存在します:`--auto-revert`と`app.autoRevert()`。 93 | 94 | ## 次のステップ {#next-steps} 95 | 96 | マイグレーション内に何を記述するかについての詳細は、[スキーマビルダー](schema.md)と[クエリビルダー](query.md)のガイドを参照してください。 -------------------------------------------------------------------------------- /docs/fluent/migration.zh.md: -------------------------------------------------------------------------------- 1 | # 迁移 2 | 3 | 迁移就像数据库的版本控制系统。每次迁移都定义了对数据库的更改以及如何撤消更改。通过迁移修改数据库,你可以创建一种一致的、可测试的和可共享的方式来随着时间演进数据库。 4 | 5 | ```swift 6 | // An example migration. 7 | struct MyMigration: Migration { 8 | func prepare(on database: any Database) -> EventLoopFuture { 9 | // Make a change to the database. 10 | } 11 | 12 | func revert(on database: any Database) -> EventLoopFuture { 13 | // Undo the change made in `prepare`, if possible. 14 | } 15 | } 16 | ``` 17 | 18 | 如果你使用 `async`/`await`,则应该实现 `AsyncMigration` 协议: 19 | 20 | ```swift 21 | struct MyMigration: AsyncMigration { 22 | func prepare(on database: any Database) async throws { 23 | // Make a change to the database. 24 | } 25 | 26 | func revert(on database: any Database) async throws { 27 | // Undo the change made in `prepare`, if possible. 28 | } 29 | } 30 | ``` 31 | 32 | `prepare` 方法是对提供的 `数据库` 进行更改的地方。这些可能是对数据库模式的更改,如添加或删除表或集合、字段或约束。他们还可以修改数据库内容,比如创建新的模型实例、更新字段值或进行清理。 33 | 34 | 如果可能的话,`revert` 方法是撤消这些更改的地方。能够撤消迁移可以使原型设计和测试更加容易。如果部署到生产环境的工作没有按计划进行,它们还会为你提供备份计划。 35 | 36 | ## 注册 37 | 38 | 迁移请使用 `app.migrations` 方法注册到你的应用程序。 39 | 40 | ```swift 41 | import Fluent 42 | import Vapor 43 | 44 | app.migrations.add(MyMigration()) 45 | ``` 46 | 47 | 你可以使用 `to` 参数指定要迁移的数据库,否则将使用默认的数据库。 48 | 49 | ```swift 50 | app.migrations.add(MyMigration(), to: .myDatabase) 51 | ``` 52 | 53 | 迁移应按依赖关系顺序列出。例如,如果 `MigrationB` 依赖 `MigrationA`,则在添加完 `MigrationA` 之后,通过 `app.migrations` 方法添加 `MigrationB`。 54 | 55 | ## 迁移 56 | 57 | 要迁移你的数据库,请在终端运行 `migrate` 命令。 58 | 59 | ```sh 60 | swift run App migrate 61 | ``` 62 | 63 | 你也可以[通过 Xcode 运行这个命令](../advanced/commands.md#xcode)。migrate 命令将检查数据库,查看自上次运行以来是否注册了新的迁移。如果有新的迁移,运行它之前会要求确认。 64 | 65 | ### 撤销 66 | 67 | 要撤消数据库上的迁移,终端运行 `migrate` 命令时添加 `--revert` 标志。 68 | 69 | ```sh 70 | swift run App migrate --revert 71 | ``` 72 | 73 | 该命令将检查数据库以查看上次运行的迁移是哪一批,并在恢复之前要求确认。 74 | 75 | ### 自动迁移 76 | 77 | 如果你希望在运行其他命令之前自动运行迁移,可以添加 `--auto-migrate` 标志。 78 | 79 | ```sh 80 | swift run App serve --auto-migrate 81 | ``` 82 | 83 | 你也可以通过编程来实现。 84 | 85 | ```swift 86 | try app.autoMigrate().wait() 87 | 88 | // or 89 | try await app.autoMigrate() 90 | ``` 91 | 92 | `--auto-revert` 和 `app.autoRevert()`,这两种方式皆可用于撤销迁移。 93 | 94 | ## 下一步 95 | 96 | 请查看[schema builder](schema.md) 和 [query builder](query.md) 指南,以了解更多迁移相关的信息。 97 | 98 | 99 | -------------------------------------------------------------------------------- /docs/fluent/transaction.es.md: -------------------------------------------------------------------------------- 1 | # Transacciones 2 | 3 | Las transacciones te permiten asegurar que múltiples operaciones se completen con éxito antes de un guardado en tu base de datos. 4 | Una vez una transacción ha empezado, puedes ejecutar consultas de Fluent de manera normal. Sin embargo, ningún dato será guardado en la base de datos hasta que la transacción se complete. 5 | Si se lanza un error en algún momento durante la transacción (por ti o por la base de datos), no se efectuará ningún cambio. 6 | 7 | Para llevar a cabo una transacción, necesitas acceso a algo que pueda conectar con la base de datos. Normalmente, esto es una petición HTTP entrante. Para esto, usa `req.db.transaction(_ :)`: 8 | 9 | ```swift 10 | req.db.transaction { database in 11 | // usar la base de datos 12 | } 13 | ``` 14 | 15 | Una vez dentro del closure de la transacción, debes usar la base de datos proporcionada en el parámetro del closure (llamado `database` en el ejemplo) para hacer consultas. 16 | 17 | Cuando este closure devuelva de manera exitosa, se hará la transacción. 18 | 19 | ```swift 20 | var sun: Star = ... 21 | var sirius: Star = ... 22 | 23 | return req.db.transaction { database in 24 | return sun.save(on: database).flatMap { _ in 25 | return sirius.save(on: database) 26 | } 27 | } 28 | ``` 29 | 30 | El ejemplo anterior guardará `sun` y *después* `sirius` antes de completar la transacción. Si falla el guardado de cualquiera de las estrellas, ninguna se guardará. 31 | 32 | Una vez la transacción se haya completado, el resultado puede transformarse en un futuro diferente, como una respuesta HTTP que indique la finalización, de manera similar al siguiente ejemplo: 33 | 34 | ```swift 35 | return req.db.transaction { database in 36 | // usa la base de datos y ejecuta la transacción 37 | }.transform(to: HTTPStatus.ok) 38 | ``` 39 | 40 | ## `async`/`await` 41 | 42 | Si usas `async`/`await` puedes refactorizar el código de la siguiente manera: 43 | 44 | ```swift 45 | try await req.db.transaction { transaction in 46 | try await sun.save(on: transaction) 47 | try await sirius.save(on: transaction) 48 | } 49 | return .ok 50 | ``` 51 | -------------------------------------------------------------------------------- /docs/fluent/transaction.fr.md: -------------------------------------------------------------------------------- 1 | # Transactions 2 | 3 | Les transactions vous permettent de garantir que plusieurs opérations se terminent avec succès avant d'enregistrer les données dans votre base de données. 4 | Une fois une transaction démarrée, vous pouvez exécuter des requêtes Fluent normalement. Cependant, aucune donnée ne sera enregistrée dans la base de données tant que la transaction n'est pas terminée. 5 | Si une erreur est générée à tout moment au cours de la transaction (par vous ou par la base de données), aucune des modifications ne prendra effet. 6 | 7 | Pour effectuer une transaction, vous devez accéder à quelque chose qui peut se connecter à la base de données. Il s'agit généralement d'une requête HTTP entrante. Pour cela, utilisez `req.db.transaction(_ :)` : 8 | ```swift 9 | req.db.transaction { database in 10 | // utiliser la base de données 11 | } 12 | ``` 13 | Une fois à l'intérieur de la closure de la transaction, vous devez utiliser la base de données fournie dans le paramètre de closure (nommée `database` dans l'exemple) pour effectuer des requêtes. 14 | 15 | Une fois cette fermeture réussie, la transaction sera validée. 16 | ```swift 17 | var sun: Star = ... 18 | var sirius: Star = ... 19 | 20 | return req.db.transaction { database in 21 | return sun.save(on: database).flatMap { _ in 22 | return sirius.save(on: database) 23 | } 24 | } 25 | ``` 26 | L'exemple ci-dessus enregistrera `sun` et *puis* `sirius` avant de terminer la transaction. Si l’une des étoiles ne parvient pas à sauvegarder, aucune des deux ne le fera. 27 | 28 | Une fois la transaction terminée, le résultat peut être transformé dans un futur différent, par exemple en un statut HTTP pour indiquer la fin, comme indiqué ci-dessous : 29 | ```swift 30 | return req.db.transaction { database in 31 | // utiliser la base de données et effectue une transaction 32 | }.transform(to: HTTPStatus.ok) 33 | ``` 34 | 35 | ## `async`/`await` 36 | 37 | Si vous utilisez `async`/`await`, vous pouvez refactoriser le code comme suit : 38 | 39 | ```swift 40 | try await req.db.transaction { transaction in 41 | try await sun.save(on: transaction) 42 | try await sirius.save(on: transaction) 43 | } 44 | return .ok 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/fluent/transaction.it.md: -------------------------------------------------------------------------------- 1 | # Transazioni 2 | 3 | Le transazioni garantiscono che varie operazioni vengano eseguite con successo prima di effettuare l'aggiornamento dei dati sul tuo database. 4 | Una volta avviata una transazione, puoi procedere con le query Fluent come al solito, tuttavia i dati non verranno effettivamente salvati sul database fino al completamento della transazione. 5 | In caso di errore durante la transazione, che sia scaturito da te o dal sistema di gestione del database, le modifiche proposte non saranno applicate. 6 | 7 | Per eseguire una transazione, devi accedere a qualcosa che si può connettere al database. Questo solitamente è una richiesta HTTP. In questo caso, usa `req.db.transaction(_ :)`: 8 | ```swift 9 | req.db.transaction { database in 10 | // usa il database 11 | } 12 | ``` 13 | Una volta dentro la chiusura della transazione, devi usare il database fornito nel parametro della chiusura (chiamato `database` nell'esempio) per eseguire query. 14 | 15 | Quando questa chiusura ritorna con successo, la transazione sarà confermata. 16 | ```swift 17 | var sun: Star = ... 18 | var sirius: Star = ... 19 | 20 | return req.db.transaction { database in 21 | return sun.save(on: database).flatMap { _ in 22 | return sirius.save(on: database) 23 | } 24 | } 25 | ``` 26 | L'esempio qui sopra salverà `sun` e *dopo* `sirius` prima di completare la transazione. Se il salvataggio di una delle due `Star` fallisce, nessuna delle due verrà salvata. 27 | 28 | Quando la transazione è completa, il risultato può essere trasformato in una future diversa, per esempio in uno status HTTP per indicare il completamento come mostrato qui sotto: 29 | ```swift 30 | return req.db.transaction { database in 31 | // usa il database e esegui la transazione 32 | }.transform(to: HTTPStatus.ok) 33 | ``` 34 | 35 | ## `async`/`await` 36 | 37 | Se usi `async`/`await` puoi ristrutturare il codice come segue: 38 | 39 | ```swift 40 | try await req.db.transaction { database in 41 | try await sun.save(on: database) 42 | try await sirius.save(on: database) 43 | } 44 | return .ok 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/fluent/transaction.ja.md: -------------------------------------------------------------------------------- 1 | # トランザクション {#transactions} 2 | 3 | トランザクションを使用すると、データベースにデータを保存する前に、複数の操作が正常に完了することを保証できます。 4 | トランザクションが開始されると、通常通りFluentクエリを実行できます。ただし、トランザクションが完了するまでデータはデータベースに保存されません。 5 | トランザクション中のいずれかの時点でエラーがスローされた場合(あなたまたはデータベースによって)、変更は一切反映されません。 6 | 7 | トランザクションを実行するには、データベースに接続できるものへのアクセスが必要です。これは通常、受信HTTPリクエストです。これには、`req.db.transaction(_ :)`を使用します: 8 | ```swift 9 | req.db.transaction { database in 10 | // databaseを使用 11 | } 12 | ``` 13 | トランザクションクロージャ内では、クロージャパラメータで提供されるデータベース(例では`database`という名前)を使用してクエリを実行する必要があります。 14 | 15 | このクロージャが正常に返されると、トランザクションがコミットされます。 16 | ```swift 17 | var sun: Star = ... 18 | var sirius: Star = ... 19 | 20 | return req.db.transaction { database in 21 | return sun.save(on: database).flatMap { _ in 22 | return sirius.save(on: database) 23 | } 24 | } 25 | ``` 26 | 上記の例では、トランザクションを完了する前に`sun`を保存し、*その後*`sirius`を保存します。いずれかの星の保存に失敗した場合、どちらも保存されません。 27 | 28 | トランザクションが完了すると、結果を別のfutureに変換できます。例えば、以下のように完了を示すHTTPステータスに変換できます: 29 | ```swift 30 | return req.db.transaction { database in 31 | // databaseを使用してトランザクションを実行 32 | }.transform(to: HTTPStatus.ok) 33 | ``` 34 | 35 | ## `async`/`await` 36 | 37 | `async`/`await`を使用する場合、コードを以下のようにリファクタリングできます: 38 | 39 | ```swift 40 | try await req.db.transaction { transaction in 41 | try await sun.save(on: transaction) 42 | try await sirius.save(on: transaction) 43 | } 44 | return .ok 45 | ``` -------------------------------------------------------------------------------- /docs/fluent/transaction.md: -------------------------------------------------------------------------------- 1 | # Transactions 2 | 3 | Transactions allow you to ensure multiple operations complete successfully before saving data to your database. 4 | Once a transaction is started, you may run Fluent queries normally. However, no data will be saved to the database until the transaction completes. 5 | If an error is thrown at any point during the transaction (by you or the database), none of the changes will take effect. 6 | 7 | To perform a transaction, you need access to something that can connect to the database. This is usually an incoming HTTP request. For this, use `req.db.transaction(_ :)`: 8 | ```swift 9 | req.db.transaction { database in 10 | // use database 11 | } 12 | ``` 13 | Once inside the transaction closure, you must use the database supplied in the closure parameter (named `database` in the example) to perform queries. 14 | 15 | Once this closure returns successfully, the transaction will be committed. 16 | ```swift 17 | var sun: Star = ... 18 | var sirius: Star = ... 19 | 20 | return req.db.transaction { database in 21 | return sun.save(on: database).flatMap { _ in 22 | return sirius.save(on: database) 23 | } 24 | } 25 | ``` 26 | The above example will save `sun` and *then* `sirius` before completing the transaction. If either star fails to save, neither will save. 27 | 28 | Once the transaction completes, the result can be transformed into a different future, for example into a HTTP status to indicate completion as shown below: 29 | ```swift 30 | return req.db.transaction { database in 31 | // use database and perform transaction 32 | }.transform(to: HTTPStatus.ok) 33 | ``` 34 | 35 | ## `async`/`await` 36 | 37 | If using `async`/`await` you can refactor the code to the following: 38 | 39 | ```swift 40 | try await req.db.transaction { transaction in 41 | try await sun.save(on: transaction) 42 | try await sirius.save(on: transaction) 43 | } 44 | return .ok 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/fluent/transaction.nl.md: -------------------------------------------------------------------------------- 1 | # Transacties 2 | 3 | Met transacties kunt u ervoor zorgen dat meerdere bewerkingen met succes worden voltooid voordat u gegevens in uw database opslaat. 4 | Zodra een transactie is gestart, kunt u Fluent queries normaal uitvoeren. Er worden echter geen gegevens in de database opgeslagen totdat de transactie is voltooid. 5 | Als er op enig moment tijdens de transactie een fout wordt gegooid (door u of door de database), zal geen van de wijzigingen effect hebben. 6 | 7 | Om een transactie uit te voeren, heb je toegang nodig tot iets dat verbinding kan maken met de database. Dit is meestal een inkomend HTTP verzoek. Gebruik hiervoor `req.db.transaction(_ :)`: 8 | ```swift 9 | req.db.transaction { database in 10 | // database gebruiken 11 | } 12 | ``` 13 | Eenmaal in de transactie closure, moet je de database die in de closure parameter is meegegeven (in het voorbeeld `database` genoemd) gebruiken om queries uit te voeren. 14 | 15 | Zodra deze afsluiting succesvol is, wordt de transactie vastgelegd. 16 | ```swift 17 | var sun: Star = ... 18 | var sirius: Star = ... 19 | 20 | return req.db.transaction { database in 21 | return sun.save(on: database).flatMap { _ in 22 | return sirius.save(on: database) 23 | } 24 | } 25 | ``` 26 | Het bovenstaande voorbeeld zal `sun` opslaan en *daarna* `sirius` alvorens de transactie te voltooien. Als een van de sterren niet opslaat, slaat geen van beide sterren op. 27 | 28 | Zodra de transactie is voltooid, kan het resultaat worden omgezet in een andere future, bijvoorbeeld in een HTTP-status om de voltooiing aan te geven, zoals hieronder afgebeeld: 29 | ```swift 30 | return req.db.transaction { database in 31 | // database gebruiken en transactie uitvoeren 32 | }.transform(to: HTTPStatus.ok) 33 | ``` 34 | 35 | ## `async`/`await` 36 | 37 | Als je `async`/`await` gebruikt kun je de code als volgt herformuleren: 38 | 39 | ```swift 40 | try await req.db.transaction { transaction in 41 | try await sun.save(on: transaction) 42 | try await sirius.save(on: transaction) 43 | } 44 | return .ok 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/fluent/transaction.zh.md: -------------------------------------------------------------------------------- 1 | # 事务 2 | 3 | 事务允许你在将数据保存到数据库之前确保多个操作成功完成。事务启动后,你可以正常运行 Fluent 查询。但是,在事务完成之前,不会将任何数据保存到数据库中。如果在事务执行期间的任何时候(由你或数据库)抛出错误,则任何更改都不会生效。 4 | 5 | 为了执行事务,你需要通过某种方式连接到数据库。这通常是一个传入的 HTTP 请求。为此,请使用 `req.db.transaction(_ :)`: 6 | ```swift 7 | req.db.transaction { database in 8 | // use database 9 | } 10 | ``` 11 | 进入事务闭包后,必须使用闭包参数中提供的数据库(在本例中名为 `database`)执行查询。 12 | 13 | 一旦这个闭包成功返回,事务将被提交。 14 | ```swift 15 | var sun: Star = ... 16 | var sirius: Star = ... 17 | 18 | return req.db.transaction { database in 19 | return sun.save(on: database).flatMap { _ in 20 | return sirius.save(on: database) 21 | } 22 | } 23 | ``` 24 | 上面的例子将在完成事务之前保存 `sun` *然后*保存 `sirius`。如果任何一项保存失败,则两者都不会被保存。 25 | 26 | 一旦事务完成,可以通过 transform(to:...) 方法将结果转换为不同的类型,例如转换为 HTTP 状态表明已完成,如下所示: 27 | ```swift 28 | return req.db.transaction { database in 29 | // use database and perform transaction 30 | }.transform(to: HTTPStatus.ok) 31 | ``` 32 | 33 | ## `async`/`await` 34 | 35 | 如果使用 `async`/`await` 你可以将代码重构为以下内容: 36 | 37 | ```swift 38 | try await req.db.transaction { transaction in 39 | try await sun.save(on: transaction) 40 | try await sirius.save(on: transaction) 41 | } 42 | return .ok 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/getting-started/folder-structure.de.md: -------------------------------------------------------------------------------- 1 | # Ordnerstruktur 2 | 3 | Lass uns einen Blick auf die Ordnerstruktur von Vapor werfen. Die Ordnerstruktur von Vapor orientiert sich an den Vorgaben des [Swift Package Managers](spm.md). Falls du schon mal mit dem SPM gearbeitet hast, sollte sie dir bekannt vorkommen. 4 | 5 | ``` 6 | . 7 | ├── Public 8 | ├── Sources 9 | │ ├── App 10 | │ │ ├── Controllers 11 | │ │ ├── Migrations 12 | │ │ ├── Models 13 | │ │ ├── configure.swift 14 | │ │ ├── entrypoint.swift 15 | │ │ └── routes.swift 16 | │ 17 | ├── Tests 18 | │ └── AppTests 19 | └── Package.swift 20 | ``` 21 | 22 | ## Public 23 | 24 | Der Ordner _Public_ beinhaltet Dateien, die sozusagen mitveröffentlicht werden. Das können Dateien für die Seitendarstellung sein, wie z. B. Bilder, CSS/JS-Dateien sein. Damit Vapor während der Ausführung auf den Ordner zugreifen kann muss eine _FileMiddleware_ in der Datei `configure.swift` mitangegeben werden. 25 | 26 | ```swift 27 | // Serves files from `Public/` directory 28 | let fileMiddleware = FileMiddleware( 29 | publicDirectory: app.directory.publicDirectory 30 | ) 31 | app.middleware.use(fileMiddleware) 32 | ``` 33 | 34 | ## Sources 35 | 36 | Im Ordner _Sources_ befinden sich die eigentlichen Anwendungsdateien deines Projektes. 37 | 38 | ### App 39 | 40 | Der Ordner _App_ beinhaltet die Anwendungslogik und stellt zudem, wie in der [Paketbeschreibung](../getting-started/spm.md) angegeben, das Modul des Paketes dar. 41 | 42 | #### Controllers 43 | 44 | Der Ordner _Controllers_ beinhaltet die Definitionen der Endpunkte der Anwendung. Mehr dazu findest du im Abschnitt [Controllers](../basics/controllers.md). 45 | 46 | #### Migrations 47 | 48 | Der Ordner _Migrations_ beinhaltet die Definitionen zu Tabellen der Datebank. 49 | 50 | #### Models 51 | 52 | Der Ordner _Models_ beinhaltet die Klassendefinitionen für die Entitäten. 53 | 54 | #### configure.swift 55 | 56 | Die Datei _configure.swift_ umfasst die Methode `configure(_:)`. Sie wird vom Einstiegspunkt aufgerufen um die Anwendung mit entsprechenden Angaben zu Endpunkten, zur Datenbank oder zu Providern zu konfigurieren. 57 | 58 | #### entrypoint.swift 59 | 60 | In der Datei _entrypoint.swift_ befindet sich der Einstiegspunkt (`@main`) für die Anwendung, von dem aus die Anwendung eingerichtet, konfiguriert und gestartet wird. 61 | 62 | #### routes.swift 63 | 64 | Die Datei _routes.swift_ beinhaltet die Methode `routes(_:)`. Sie wird am Ende von der `configure(_:)`-Methode aufgerufen um die Endpunkte zu registrieren. 65 | 66 | ## Tests 67 | 68 | Für jedes Paketmodul kann ein entsprechender Ordner unter _Tests_ angelegt werden. 69 | 70 | ### AppTests 71 | 72 | Der Ornder _AppTests_ beinhaltet alle möglichen Tests für Komponenten der Anwendung. 73 | 74 | ## Package.swift 75 | 76 | Die Datei _Package.swift_ ist die Paketbeschreibung. 77 | -------------------------------------------------------------------------------- /docs/getting-started/folder-structure.ja.md: -------------------------------------------------------------------------------- 1 | # フォルダ構造 {#folder-structure} 2 | 3 | あなたの初めての Vapor アプリを作成し、ビルドし、実行したので、Vapor のフォルダ構造に慣れるための時間を取りましょう。この構造は、[SPM](spm.ja.md) のフォルダ構造に基づいていますので、以前に SPM を使ったことがあれば、見慣れているはずです。 4 | 5 | ``` 6 | . 7 | ├── Public 8 | ├── Sources 9 | │ ├── App 10 | │ │ ├── Controllers 11 | │ │ ├── Migrations 12 | │ │ ├── Models 13 | │ │ ├── configure.swift 14 | │ │ ├── entrypoint.swift 15 | │ │ └── routes.swift 16 | │ 17 | ├── Tests 18 | │ └── AppTests 19 | └── Package.swift 20 | ``` 21 | 22 | 以下のセクションでは、フォルダ構造の各部分について詳しく説明します。 23 | 24 | ## Public 25 | 26 | このフォルダには、`FileMiddleware` が有効になっている場合にアプリによって提供される公開ファイルが含まれます。これは通常、画像やスタイルシート、ブラウザスクリプトです。例えば、`localhost:8080/favicon.ico` へのリクエストは、`Public/favicon.ico` が存在するかどうかを確認し、それを返します。 27 | 28 | Vapor が公開ファイルを提供できるようにする前に、`configure.swift` ファイルで `FileMiddleware` を有効にする必要があります。 29 | 30 | ```swift 31 | // Serves files from `Public/` directory 32 | let fileMiddleware = FileMiddleware( 33 | publicDirectory: app.directory.publicDirectory 34 | ) 35 | app.middleware.use(fileMiddleware) 36 | ``` 37 | 38 | ## Sources 39 | 40 | このフォルダには、プロジェクトのすべての Swift ソースファイルが含まれています。 41 | トップレベルのフォルダ、`App` は、[SwiftPM](spm.ja.md) のマニフェストで宣言されたパッケージのモジュールを反映しています。 42 | 43 | ### App 44 | 45 | ここには、アプリケーションの全てのロジックが入ります。 46 | 47 | #### Controllers 48 | 49 | Controllers は、アプリケーションのロジックをまとめるのに適しています。ほとんどのコントローラには、リクエストを受け取り、何らかの形でレスポンスを返す多くの関数があります。 50 | 51 | #### Migrations 52 | 53 | Migrations フォルダは、Fluent を使用している場合、データベースの移行を格納する場所です。 54 | 55 | #### Models 56 | 57 | Models フォルダは、`Content` 構造体や Fluent の `Model` を保存するのに適しています。 58 | 59 | #### configure.swift {#configureswift} 60 | 61 | このファイルには、`configure(_:)` 関数が含まれています。このメソッドは、新しく作成された `Application` を設定するために `entrypoint.swift` から呼び出されます。ここで、ルート、データベース、プロバイダなどのサービスの登録をする必要があります。 62 | 63 | #### entrypoint.swift {#entrypointswift} 64 | 65 | このファイルには、Vapor アプリケーションの設定と実行を行うアプリケーションの `@main` エントリーポイントが含まれています。 66 | 67 | #### routes.swift {#routesswift} 68 | 69 | このファイルには、`routes(_:)` 関数が含まれています。このメソッドは、`Application` へのルートを登録するために、`configure(_:)` の終わり近くで呼び出されます。 70 | 71 | ## Tests 72 | 73 | `Sources` フォルダ内の各非実行可能モジュールには、`Tests` の対応するフォルダがあります。これには、パッケージのテストのために `XCTest` モジュールに基づいてビルドされたコードが含まれています。テストは、コマンドラインで `swift test` を使用するか、Xcode で ⌘+U を押すと実行できます。 74 | 75 | ### AppTests 76 | 77 | このフォルダには、`App` モジュールのコードの単体テストが含まれています。 78 | 79 | ## Package.swift {#packageswift} 80 | 81 | 最後に、[SPM](spm.ja.md) のパッケージマニフェストがあります。 82 | -------------------------------------------------------------------------------- /docs/getting-started/folder-structure.ko.md: -------------------------------------------------------------------------------- 1 | # 폴더 구조 2 | 3 | 이제 첫 번째 Vapor 앱을 만들고 빌드하고 실행했으니, Vapor의 폴더 구조에 익숙해지는 시간을 가져보겠습니다. 이 구조는 SPM의 폴더 구조를 기반으로 하기 때문에, 이전에 [SPM](spm.ko.md)을 사용한 적이 있다면 익숙할 것입니다. 4 | 5 | ``` 6 | . 7 | ├── Public 8 | ├── Sources 9 | │ ├── App 10 | │ │ ├── Controllers 11 | │ │ ├── Migrations 12 | │ │ ├── Models 13 | │ │ ├── configure.swift 14 | │ │ ├── entrypoint.swift 15 | │ │ └── routes.swift 16 | │ 17 | ├── Tests 18 | │ └── AppTests 19 | └── Package.swift 20 | ``` 21 | 22 | 아래의 섹션에서는 폴더 구조의 각 부분을 자세히 설명합니다. 23 | 24 | ## Public 25 | 26 | 이 폴더에는 `FileMiddleware`가 활성화된 경우 앱에서 제공되는 공개 파일이 포함됩니다. 일반적으로 이미지, 스타일 시트 및 브라우저 스크립트가 여기에 포함됩니다. 예를 들어, `localhost:8080/favicon.ico`로의 요청은 `Public/favicon.ico` 파일의 존재 여부를 확인하고 해당 파일을 반환합니다. 27 | 해당 [https://design.vapor.codes/favicons/favicon.ico](https://design.vapor.codes/favicons/favicon.ico)에 접속하면 Vapor로고 이미지를 확인할 수 있습니다. 28 | 29 | Vapor가 공개 파일을 제공하기 위해선 `configure.swift` 파일에서 `FileMiddleware`를 활성화해야 합니다. 30 | 31 | 32 | ```swift 33 | // Serves files from `Public/` directory 34 | let fileMiddleware = FileMiddleware( 35 | publicDirectory: app.directory.publicDirectory 36 | ) 37 | app.middleware.use(fileMiddleware) 38 | ``` 39 | 40 | ## Sources 41 | 42 | 이 폴더에는 프로젝트의 모든 Swift 소스 파일이 포함됩니다. 43 | 최상위 폴더인 `App`은 [SwiftPM](spm.ko.md) 매니페스트에서 선언된 패키지 모듈을 반영합니다. 44 | 45 | ### App 46 | 47 | 이 폴더는 애플리케이션 로직이 모두 들어가는 곳입니다. 48 | 49 | #### Controllers 50 | 51 | 컨트롤러는 애플리케이션 로직을 그룹화하는 좋은 방법입니다. 대부분의 컨트롤러에는 요청을 받아들이고 어떤 형태의 응답을 반환하는 많은 함수가 있습니다. 52 | 53 | #### Migrations 54 | 55 | 마이그레이션 폴더는 Fluent를 사용하는 경우 데이터베이스 마이그레이션을 위한 곳입니다. 56 | 57 | #### Models 58 | 59 | 모델 폴더는 `Content` 구조체나 Fluent `Model`을 저장하기 좋은 장소입니다. 60 | 61 | #### configure.swift 62 | 63 | 이 파일에는 `configure(_:)` 함수가 포함되어 있습니다. 이 메서드는 `entrypoint.swift`에 의해 호출되어 새로 생성된 `Application`을 구성합니다. 여기에서 라우트, 데이터베이스, 프로바이더 등과 같은 서비스를 등록해야 합니다. 64 | 65 | #### entrypoint.swift 66 | 67 | 이 파일에는 Vapor 애플리케이션을 설정, 구성 및 실행하는 `@main` 진입점이 포함되어 있습니다. 68 | 69 | #### routes.swift 70 | 71 | 이 파일에는 `routes(_:)` 함수가 포함되어 있습니다. 이 메서드는 `configure(_:)`의 마지막 부분에서 `Application`에 라우트를 등록하는 데 사용됩니다. 72 | 73 | ## Tests 74 | 75 | `Sources` 폴더의 각 비실행(non-executable) 모듈은 `Tests`에 해당하는 폴더를 가질 수 있습니다. 이 폴더에는 패키지를 테스트하기 위해 `XCTest` 모듈을 기반으로 작성된 코드가 포함됩니다. 테스트는 명령줄에서 `swift test`를 사용하거나 Xcode에서 ⌘+U를 눌러 실행할 수 있습니다. 76 | 77 | ### AppTests 78 | 79 | 이 폴더에는 `App` 모듈의 코드를 위한 단위 테스트가 포함되어 있습니다. 80 | 81 | ## Package.swift 82 | 83 | 마지막으로 [SPM](spm.ko.md)의 패키지 매니페스트가 있습니다. 84 | -------------------------------------------------------------------------------- /docs/getting-started/folder-structure.zh.md: -------------------------------------------------------------------------------- 1 | # 项目结构 2 | 3 | 现在,你已经创建并运行了第一个 Vapor 应用程序,让我们稍微花点时间熟悉一下 Vapor 的项目结构。该结构是在 [SPM](spm.zh.md) 的基础上演化而来;因此,如果你曾经使用过 SPM,应该会很熟悉。 4 | 5 | 6 | ``` 7 | . 8 | ├── Public 9 | ├── Sources 10 | │ ├── App 11 | │ │ ├── Controllers 12 | │ │ ├── Migrations 13 | │ │ ├── Models 14 | │ │ ├── configure.swift 15 | │ │ ├── entrypoint.swift 16 | │ │ └── routes.swift 17 | │ 18 | ├── Tests 19 | │ └── AppTests 20 | └── Package.swift 21 | ``` 22 | 23 | 下面将详细地解释每个文件夹的作用。 24 | 25 | ## Public 26 | 27 | 如果你使用了 `FileMiddleware` 中间件,那么此文件夹包含你的应用程序提供的所有公共文件,通常是图片、`.css` 样式和浏览器脚本等。 例如,对 `localhost:8080/favicon.ico` 发起的请求将检查是否存在 `Public/favicon.ico` 图片并回应。 28 | 29 | 在 Vapor 可以提供公共文件之前,你需要在 `configure.swift` 文件中启用`FileMiddleware`,参考如下所示: 30 | 31 | ```swift 32 | // 从 'Public/' 目录提供文件 33 | let fileMiddleware = FileMiddleware( 34 | publicDirectory: app.directory.publicDirectory 35 | ) 36 | app.middleware.use(fileMiddleware) 37 | ``` 38 | 39 | ## Sources 40 | 41 | 此文件夹包含项目的所有 Swift 源文件。 顶级文件夹 `App` 反映了你的包的模块,如 [SwiftPM](spm.md) 清单中声明的那样。 42 | 43 | ### App 44 | 45 | 应用程序的所有核心代码都包含在这里。 46 | 47 | #### Controllers 48 | 49 | 控制器是将应用程序的不同逻辑进行分组的优秀方案,大多数控制器都具备接受多种请求的功能,并根据需要进行响应。 50 | 51 | #### Migrations 52 | 53 | 如果你使用 Fluent,则可以在 Migrations 文件夹中进行数据库迁移。 54 | 55 | #### Models 56 | 57 | models 文件夹常用于存放 `Content` 和 Fluent `Model` 的类或结构体。 58 | 59 | #### configure.swift 60 | 61 | 这个文件包含 `configure(_:)` 函数,`entrypoint.swift` 调用这个方法用以配置新创建的 `Application` 实例。你可以在这里注册诸如路由、数据库、providers 等服务。 62 | 63 | #### entrypoint.swift 64 | 65 | 该文件包含应用程序的 `@main` 入口点,用于设置、配置和运行 Vapor 应用程序。 66 | 67 | #### routes.swift 68 | 69 | 这个文件包含 `routes(_:)` 方法,它会在 `configure(_:)` 结尾处被调用,用以将路由注册到你的 `Application`。 70 | 71 | ## Tests 72 | 73 | `Sources` 文件夹中的每个不可运行的模块在 `Tests` 中都可以创建一个对应的文件夹,包含 `XCTest` 模块上构建的用例,用来测试你的代码。可以在命令行使用 `swift test`或在 Xcode 中按 `⌘+U` 来进行测试。 74 | 75 | ### AppTests 76 | 77 | 此文件夹包含 `App` 模块中代码的单元测试。 78 | 79 | ## Package.swift 80 | 81 | 最后是 [SPM](spm.zh.md) 文件,是这个项目运行所依赖的第三方库配置。 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/getting-started/hello-world.de.md: -------------------------------------------------------------------------------- 1 | # Hallo Welt! 2 | 3 | In diesem Abschnitt erklären wir dir Schritt für Schritt, wie du ein Vapor-Projekt erstellst und ausführst. Sollte dir _Swift_ oder die _Vapor Toolbox_ noch fehlen, werfe zuerst einen Blick in die beiden Abschnitte [Installation → macOS](../install/macos.md) und [Installation → Linux](../install/linux.md). 4 | 5 | 6 | ## Projekt erstellen 7 | 8 | Starte die Terminal-App auf deinem Mac und führe den Toolbox-Befehl aus. Der Befehl erstellt einen Projektordner mitsamt den Dateien. 9 | 10 | ```sh 11 | vapor new hello -n 12 | ``` 13 | 14 | Sobald der Befehl durchgelaufen ist, wechsele in den neuen Ordner mit dem Befehl 15 | 16 | ```sh 17 | cd hello 18 | ``` 19 | 20 | ## Projekt ausführen 21 | 22 | Je nach System oder Entwicklungsumgebung muss das Projekt unterschiedlich ausgeführt werden: 23 | 24 | ### - mit Xcode 25 | 26 | Öffne das Projekt mit dem Befehl 27 | 28 | ```sh 29 | open Package.swift 30 | ``` 31 | 32 | Xcode öffnet sich und lädt zugleich alle notwendigen Paketverweise. Nach dem Laden sollte dir Xcode zur Verfügung stehen. Wähle anschließend in der Mitte eine Schema (oft einfach nur "My Mac") aus. Starte nun das Projekt über die Menüpunkte _Product_ > _Run_. Du solltest nun in der Konsole einen Eintrag wie diesen sehen: 33 | 34 | ```sh 35 | [ INFO ] Server starting on http://127.0.0.1:8080 36 | ``` 37 | 38 | ### - mit Linux 39 | 40 | Für Linux-Distributionen (oder falls du einfach kein Xcode verwendest) kannst du den Editor deiner Wahl nutzen, wie z.B. Vim oder VSCode. Mehr Informationen dazu, findest du im Abschnitt [Swift Server Guides](https://github.com/swift-server/guides/blob/main/docs/setup-and-ide-alternatives.md). 41 | 42 | Starte das Projekt mit dem Befehl 43 | 44 | ```sh 45 | swift run 46 | ``` 47 | 48 | Bei der Erstausführung werden die Paketverweise nachgeladen. Dementsprechend kann die Erstellung ein wenig brauchen. Nach dem Laden solltest einen Eintrag im Terminal sehen 49 | 50 | ```sh 51 | [ INFO ] Server starting on http://127.0.0.1:8080 52 | ``` 53 | 54 | ## Aufruf im Browser 55 | 56 | Rufe die Seite über den Link localhost:8080/hello oder http://127.0.0.1:8080 im Browser auf. Als Ergebnis sollte "Hello World" im Browser erscheinen. 57 | 58 | Das wars! Geschafft! Gratulation zur ersten Vapor-Anwendung. 🎉 59 | -------------------------------------------------------------------------------- /docs/getting-started/hello-world.ja.md: -------------------------------------------------------------------------------- 1 | # Hello, world 2 | 3 | このガイドは、新しい Vapor プロジェクトを作成、ビルド、サーバーを実行する手順を説明します。 4 | 5 | まだ、Swift や Vapor ツールボックスをインストールしていない場合は、インストールセクションを参照してください。 6 | 7 | - [Install → macOS](../install/macos.ja.md) 8 | - [Install → Linux](../install/linux.ja.md) 9 | 10 | !!! tip 11 | Vapor ツールボックスで使用されるテンプレートには Swift 6.0 以降が必要です 12 | 13 | ## 新規プロジェクト {#new-project} 14 | 15 | 最初のステップは、コンピュータに新しい Vapor プロジェクトを作成することです。ターミナルを開き、ツールボックスの新規プロジェクトコマンドを使用してください。これにより、現在のディレクトリにプロジェクトを含む新しいフォルダが作成されます。 16 | 17 | ```sh 18 | vapor new hello -n 19 | ``` 20 | 21 | !!! tip 22 | `-n` フラグは、すべての質問に自動的に「いいえ」と答えることで、ベアボーンのテンプレートを提供します。 23 | 24 | !!! tip 25 | Vapor ツールボックスを使用せずに GitHub [テンプレートリポジトリ](https://github.com/vapor/template-bare)をクローンして最新のテンプレートを取得することもできます。 26 | 27 | !!! tip 28 | Vapor とテンプレートは、デフォルトで `async`/`await` を使用します。 29 | macOS 12 にアップデートできない、または `EventLoopFuture` を継続して使用する必要がある場合は、 30 | `--branch macos10-15` フラグを使います。 31 | 32 | コマンドが完了したら、新しく作成されたフォルダに移動します。 33 | 34 | 35 | ```sh 36 | cd hello 37 | ``` 38 | 39 | ## ビルド & 実行 {#build-run} 40 | 41 | ### Xcode 42 | 43 | まず、Xcode でプロジェクトを開きます: 44 | 45 | ```sh 46 | open Package.swift 47 | ``` 48 | 49 | 自動的に Swift Package Manager の依存関係をダウンロードし始めます。プロジェクトを初めて開くとき、時間がかかることがあります。依存関係の解決が完了すると、Xcode は利用可能なスキームを表示します。 50 | 51 | ウィンドウの上部に、再生ボタンと停止ボタンの右側にあるプロジェクト名をクリックして、プロジェクトのスキームを選択します。適切な実行ターゲットを選択してください。おそらく、"My Mac" が適しているでしょう。プレイボタンをクリックして、プロジェクトをビルドして実行します。 52 | 53 | Xcode のウィンドウの下部に、コンソールが表示されるはずです。 54 | 55 | ```sh 56 | [ INFO ] Server starting on http://127.0.0.1:8080 57 | ``` 58 | 59 | ### Linux 60 | 61 | Linux やその他 OS (または Xcode を使用したくない場合の macOS も含む)では、 Vim や VScode のようなお好きなエディタでプロジェクトを編集できます。他の IDE の設定に関する最新の詳細は、[Swift Server ガイド](https://github.com/swift-server/guides/blob/main/docs/setup-and-ide-alternatives.md)を参照してください。 62 | 63 | !!! tip 64 | VSCode をコードエディタとして使用している場合は、公式の Vapor 拡張機能をインストールすることをお勧めします: [Vapor for VS Code](https://marketplace.visualstudio.com/items?itemName=Vapor.vapor-vscode) 65 | 66 | プロジェクトをビルドして実行するには、ターミナルで以下のコマンドを実行します: 67 | 68 | ```sh 69 | swift run 70 | ``` 71 | 72 | これにより、プロジェクトがビルドされて実行されます。初めてこれを実行すると、依存関係を取得および解決するのに時間がかかります。実行が開始されると、コンソールに以下の内容が表示されるはずです: 73 | 74 | ```sh 75 | [ INFO ] Server starting on http://127.0.0.1:8080 76 | ``` 77 | 78 | ## Localhost へのアクセス {#visit-localhost} 79 | 80 | ウェブブラウザを開き、localhost:8080/hello または http://127.0.0.1:8080 にアクセスしてください。 81 | 82 | 次のページが表示されるはずです。 83 | 84 | 85 | ```html 86 | Hello, world! 87 | ``` 88 | 89 | おめでとうございます! Vapor アプリの作成、ビルド、実行することに成功しました! 🎉 90 | -------------------------------------------------------------------------------- /docs/getting-started/hello-world.ko.md: -------------------------------------------------------------------------------- 1 | # Hello, world 2 | 3 | 해당 가이드문서에서는 새로운 Vapor 프로젝트를 만들고, 빌드하고, 서버를 실행하는 단계별 절차를 안내합니다. 4 | 5 | 아직 Swift 또는 Vapor Toolbox를 설치하지 않았다면 하단에 운영체제에 맞게 설치하기 문서를 확인하세요. 6 | 7 | - [Install → macOS](../install/macos.ko.md) 8 | - [Install → Linux](../install/linux.ko.md) 9 | 10 | ## 새 프로젝트 생성하기 11 | 12 | 첫 번째 단계는 컴퓨터에 새로운 Vapor 프로젝트를 만드는 것입니다. 터미널을 열고 Toolbox의 새 프로젝트 명령을 사용하세요. 이렇게 하면 현재 디렉토리에 새 폴더가 생성되며 프로젝트가 포함됩니다. 13 | 14 | ```sh 15 | vapor new hello -n 16 | ``` 17 | 18 | !!! 팁 19 | `-n` 플래그를 사용하면 모든 질문에 자동으로 "no"로 대답하여 기본 템플릿을 얻을 수 있습니다. 20 | 21 | !!! 팁 22 | Vapor Toolbox 없이도 [템플릿 저장소](https://github.com/vapor/template-bare)를 클론하여 GitHub에서 최신 템플릿을 사용할 수 있습니다. 23 | 24 | !!! 팁 25 | Vapor와 템플릿은 이제 기본적으로 `async`/`await`을 사용합니다. macOS 12로 업데이트할 수 없거나 EventLoopFuture를 계속 사용해야 하는 경우 `--branch macos10-15` 플래그를 사용하세요. 26 | 27 | 명령이 완료되면 새로 생성된 폴더로 이동하세요. 28 | 29 | 30 | ```sh 31 | cd hello 32 | ``` 33 | 34 | ## 빌드 & 실행 35 | 36 | ### Xcode 37 | 38 | 먼저, Xcode에서 프로젝트를 엽니다. 39 | 40 | ```sh 41 | open Package.swift 42 | ``` 43 | 44 | Swift Package Manager 종속성을 자동으로 다운로드하기 시작합니다. 이는 프로젝트를 처음 열 때는 시간이 걸릴 수 있습니다. 종속성 해결이 완료되면 Xcode에서 사용 가능한 스키마가 표시됩니다. 45 | 46 | 창 상단에서 재생 및 정지 버튼 오른쪽에 프로젝트 이름을 클릭하여 프로젝트의 스키마를 선택하고 적절한 실행 대상(아마도 "My Mac")을 선택하세요. 재생 버튼을 클릭하여 프로젝트를 빌드하고 실행합니다. 47 | 48 | Xcode 창 하단에 콘솔이 아래처럼 보일 것입니다. 49 | 50 | ```sh 51 | [ INFO ] Server starting on http://127.0.0.1:8080 52 | ``` 53 | 54 | ### Linux 55 | 56 | Linux 및 다른 운영 체제(또는 macOS에서 Xcode를 사용하지 않을 경우)에서는 Vim이나 VSCode와 같은 즐겨찾는 편집기에서 프로젝트를 편집할 수 있습니다. 다른 IDE를 설정하는 방법에 대한 최신 정보는 [Swift Server Guides](https://github.com/swift-server/guides/blob/main/docs/setup-and-ide-alternatives.md)를 참조하세요. 57 | 58 | 프로젝트를 빌드하고 실행하려면 터미널에서 다음 명령을 실행합니다. 59 | 60 | ```sh 61 | swift run 62 | ``` 63 | 64 | 이 명령은 프로젝트를 빌드하고 실행합니다. 처음 실행할 때는 종속성을 가져오고 해결하는 데 시간이 걸립니다. 실행 중에는 콘솔에서 다음과 같은 출력을 볼 수 있어야 합니다. 65 | 66 | ```sh 67 | [ INFO ] Server starting on http://127.0.0.1:8080 68 | ``` 69 | 70 | ## Localhost 접속해보기 71 | 72 | 웹 브라우저를 열고, localhost:8080/hello 또는 http://127.0.0.1:8080을 접속해봅니다. 73 | 74 | 해당 웹페이지에서는 다음과 같이 표시되어야 합니다. 75 | 76 | ```html 77 | Hello, world! 78 | ``` 79 | 80 | 첫 번째 Vapor앱을 만들고 빌드하고 실행한 것을 축하드립니다! 🎉 81 | -------------------------------------------------------------------------------- /docs/getting-started/hello-world.zh.md: -------------------------------------------------------------------------------- 1 | 2 | # 你好,世界 3 | 4 | 本文将指引你逐步创建、编译并运行 Vapor 的项目。 5 | 6 | 如果尚未安装 Swift 和 Vapor Toolbox,请查看安装部分。 7 | 8 | - [安装 → macOS](../install/macos.md) 9 | - [安装 → Linux](../install/linux.md) 10 | 11 | ## 创建 12 | 13 | 首先,在电脑上创建 Vapor 项目。打开终端并使用以下 Toolbox 的命令行,这将会在当前目录创建一个包含 Vapor 项目的文件夹。 14 | 15 | ```sh 16 | vapor new hello -n 17 | ``` 18 | 19 | !!! tip "建议" 20 | 使用 `-n` 为所有的问题自动选择 no 来为你提供一个基本的模板。 21 | 22 | !!! tip "建议" 23 | 你也可以不使用 Vapor Toolbox,直接从 GitHub 克隆[模板库](https://github.com/vapor/template-bare)来获取最新的模板。 24 | 25 | !!! tip "建议" 26 | Vapor 以及自带的模板默认使用 `async`/`await`。如果你的系统不能更新到 macOS 12 或者想继续使用 `EventLoopFuture`。运行命令时可以添加此标志 `--branch macos10-15`。 27 | 28 | 命令完成后,切换到新创建的文件夹 29 | 30 | ```sh 31 | cd hello 32 | ``` 33 | 34 | ## 编译 & 运行 35 | 36 | ### Xcode 37 | 38 | 首先,在Xcode打开项目: 39 | 40 | ```sh 41 | open Package.swift 42 | ``` 43 | 44 | 45 | Xcode 将自动开始下载 Swift 包管理器依赖,在第一次打开一个项目时,这可能需要一些时间,当依赖下载后,Xcode 将显示可以用的 Scheme。 46 | 47 | 在窗口的顶部,在 Play 和 Stop 按钮的右侧,单击项目名称以选择项目的 Scheme,并选择一个适当的 target ——大概率是 “My Mac”。单击 play 按钮编译并运行项目。 48 | 49 | 你应该会在 Xcode 窗口的底部看到控制台输出以下信息。 50 | 51 | ```sh 52 | [ INFO ] Server starting on http://127.0.0.1:8080 53 | ``` 54 | 55 | ### Linux 56 | 57 | 在 Linux 和其他操作系统上(甚至在 macOS 上如果你不想使用 Xcode),你可以在你喜欢的编辑器中编辑项目,比如 Vim 或 VSCode 。关于设置其他 IDE 的最新细节,请参阅 [Swift Server Guides](https://github.com/swift-server/guides/blob/main/docs/setup-and-ide-alternatives.md)。 58 | 59 | 在终端运行以下命令来编译和运行你的项目。 60 | 61 | ```sh 62 | swift run 63 | ``` 64 | 它将构建并运行项目。第一次运行时,需要花费一些时间来获取和下载依赖项。一旦运行,你应该在你的控制台中看到以下内容: 65 | 66 | ```sh 67 | [ INFO ] Server starting on http://127.0.0.1:8080 68 | ``` 69 | 70 | ## 访问 Localhost 71 | 72 | 打开你的浏览器,然后访问 localhost:8080/hello 或者 http://127.0.0.1:8080 73 | 74 | 你将看见以下页面 75 | 76 | ```html 77 | Hello, world! 78 | ``` 79 | 80 | 恭喜你创建,构建,运行了你的第一个 Vapor 应用!🎉 81 | -------------------------------------------------------------------------------- /docs/getting-started/spm.zh.md: -------------------------------------------------------------------------------- 1 | # Swift Package Manager 2 | 3 | [Swift Package Manager](https://swift.org/package-manager/)(SPM) 用于构建项目的源代码和依赖项。由于 Vapor 严重依赖 SPM,因此最好了解其工作原理。 4 | 5 | SPM 与 Cocoapods,Ruby gems 和 NPM 相似。你可以在命令行中将 SPM 与 `swift build`、`swift test` 等命令或兼容的 IDE 结合使用。但是,与其他软件包管理器不同,SPM 软件包没有中央软件包索引。SPM 使用 [Git 标签](https://git-scm.com/book/en/v2/Git-Basics-Tagging) 和 URL 来获取 Git 存储库和依赖版本。 6 | 7 | ## Package Manifest 8 | 9 | SPM 在项目中查找的第一项是 package 清单。它应始终位于项目的根目录中,并命名为 `Package.swift`。 10 | 11 | 看一下这个示例: 12 | 13 | ```swift 14 | // swift-tools-version:5.8 15 | import PackageDescription 16 | 17 | let package = Package( 18 | name: "MyApp", 19 | platforms: [ 20 | .macOS(.v12) 21 | ], 22 | dependencies: [ 23 | .package(url: "https://github.com/vapor/vapor.git", from: "4.76.0"), 24 | ], 25 | targets: [ 26 | .executableTarget( 27 | name: "App", 28 | dependencies: [ 29 | .product(name: "Vapor", package: "vapor") 30 | ] 31 | ), 32 | .testTarget(name: "AppTests", dependencies: [ 33 | .target(name: "App"), 34 | .product(name: "XCTVapor", package: "vapor"), 35 | ]) 36 | ] 37 | ) 38 | ``` 39 | 40 | 下面将对这段代码的各部分进行说明。 41 | 42 | ### Tools Version 43 | 44 | 第一行表示需要使用的 Swift tools 版本号,它指明了 Swift 的最低可用版本。Package 描述 API 可能随着 Swift 版本而改变,所以这一行将让 Swift 确认怎么去解析你的配置文件。 45 | 46 | ### Package Name 47 | 48 | `Package` 的第一个参数代表当前 package 的名字。如果软件包是公共的,你应该使用 Git 存储库的 URL 的最后一段作为名称 49 | 50 | ### Platforms 51 | 52 | `platforms` 数组指定此程序包支持的平台和版本。通过指定 `.macOS(.v12)`,说明此软件包需要 macOS 12 或更高版本。 Xcode 加载该项目时,它将最低部署版本设置为 macOS 12,以便你可以使用所有可用的 API。 53 | 54 | ### Dependencies 55 | 56 | dependencies 字段代表项目需要依赖的 package。所有 Vapor 应用都依赖 Vapor package ,但是你也可以添加其它想要的依赖库。 57 | 58 | 如上面这个示例,[vapor/vapor](https://github.com/vapor/vapor) 4.76.0 或以上版本是这个 package 的 dependency。当在 package 中添加了 dependency 后,接下来你必须设置是哪个 targets 依赖了新的可用模块。 59 | 60 | ### Targets 61 | 62 | Targets 是你的 package 里包含 modules、executables 以及 tests 总和。虽然可以添加任意多的 targets 来组织代码,但大部分 Vapor 应用有 2 个 target 就足够了。每个 target 声明了它依赖的 module。为了在代码中可以 import 这些 modules ,你必须在这里添加 module 名字。一个 target 可以依赖于工程中其它的 target 或者任意你添加在 [dependencies](#dependencies) 数组中且暴露出来的 modules。 63 | 64 | ## 目录结构 65 | 66 | 以下是典型的 SPM package 目录结构。 67 | 68 | ``` 69 | . 70 | ├── Sources 71 | │ └── App 72 | │ └── (Source code) 73 | ├── Tests 74 | │ └── AppTests 75 | └── Package.swift 76 | ``` 77 | 78 | 每个 `.target` 或 `.executableTarget` 对应于 `Sources` 中的一个文件夹。 79 | 每个 `.testTarget` 对应 `Tests` 中的一个文件夹。 80 | 81 | ## Package.resolved 82 | 83 | 第一次构建成功后,SPM 将会自动创建一个 `Package.resolved` 文件。`Package.resolved` 保存了当前项目所有用到的依赖库版本。下一次当你构建你的项目时将会同样的版本,甚至是这些依赖有更新的版本时也不会使用。 84 | 85 | 更新依赖, 运行 `swift package update`. 86 | 87 | ## Xcode 88 | 89 | 如果使用 Xcode 11 或更高版本,则在修改 `Package.swift` 文件时,将自动更改 dependencies、targets、products 等。 90 | 91 | 如果要更新到最新的依赖项,请使用 File → Swift Packages → 更新到最新的 Swift Package 版本。 92 | 93 | 你可能还想将 `.swiftpm` 文件添加到你的 `.gitignore` 文件中(Xcode 在此处存储 Xcode 项目配置)。 94 | -------------------------------------------------------------------------------- /docs/getting-started/xcode.de.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | Dieser Abschnitt geht auf Tipps und Tricks zur Verwendung von Vapor in Xcode ein. Solltest du eine andere Entwicklungsumgebung verwenden, kannst du natürlich den Abschnitt überspringen. 4 | 5 | ## Arbeitsverzeichnis 6 | 7 | Xcode greift standardmäßig auf den _Derived Data_-Ordner zu. Der Ordner ist fälschlicherweise jedoch nicht das Arbeitsverzeichnis deines Projektes, weshalb Vapor beispielweise den _Public_-Ordner oder die Datei mit Umgebungsvariablen nicht vorfinden kann. Xcode gibt daraufhin eine Fehlermeldung aus: 8 | 9 | ``` 10 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 11 | ``` 12 | 13 | Um das Problem zu lösen, musst du den Pfad zu deinem Projekt in Schemen-Editor hinterlegen. Rufe über die den Menüpunkte _Products > Scheme > Edit Scheme..._ den Editor auf und wähle das Schema _App_ aus. 14 | 15 | Klicke in der rechten Fensterhälfte auf den Reiter _Options_ und gebe unter dem Punkt _Working Directory_ den Pfad zu deinem Projekt mit an. 16 | 17 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 18 | 19 | Für den Fall, dass du den Pfad zu deinem Projekt nicht kennst, kannst du mit Hilfe des Terminal-Befehls 'pwd' den Pfad ganz einfach herausfinden. 20 | 21 | ```sh 22 | # get path to this folder 23 | pwd 24 | ``` 25 | 26 | ``` 27 | /path/to/project 28 | ``` -------------------------------------------------------------------------------- /docs/getting-started/xcode.es.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | Esta página repasa algunos trucos y consejos para usar Xcode. Si usas un entorno de desarrollo distinto, puedes omitir esta parte. 4 | 5 | ## Custom Working Directory 6 | 7 | Por defecto, Xcode ejecutará tu proyecto desde la carpeta _DerivedData_. Esta carpeta es otra distinta a la carpeta raíz de tu proyecto (donde se encuentra tu fichero _Package.swift_). Esto quiere decir que Vapor no será capaz de encontrar ficheros y carpetas como _.env_ o _Public_. 8 | 9 | Puedes averiguar que esto está sucediendo si al ejecutar tu proyecto recibes el siguiente aviso. 10 | 11 | ```fish 12 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 13 | ``` 14 | 15 | Para solucionarlo, establece un directorio de trabajo personalizado para tu proyecto en el esquema de Xcode. 16 | 17 | Primero, edita el esquema de tu proyecto pulsando en el selector de esquemas junto a los botones de play y stop. 18 | 19 | ![Xcode Scheme Area](../images/xcode-scheme-area.png) 20 | 21 | Selecciona _Edit Scheme..._ en el menú desplegable. 22 | 23 | ![Xcode Scheme Menu](../images/xcode-scheme-menu.png) 24 | 25 | En el editor de esquemas, elige la acción _App_ y la pestaña _Options_. Selecciona _Use custom working directory_ e ingresa la dirección de la carpeta raíz de tu proyecto. 26 | 27 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 28 | 29 | Puedes obtener la dirección completa a la raíz de tu proyecto ejecutando `pwd` en una ventana de terminal ubicada en el proyecto. 30 | 31 | ```sh 32 | # obtener la dirección de la carpeta 33 | pwd 34 | ``` 35 | 36 | Deberías obtener una salida similar a la que se muestra a continuación. 37 | 38 | ``` 39 | /path/to/project 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/getting-started/xcode.it.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | Questa pagina contiene alcuni consigli e trucchi per l'utilizzo di Xcode. Puoi saltarla se preferisci usare un ambiente di sviluppo diverso. 4 | 5 | ## Directory di lavoro personalizzata 6 | 7 | Di default Xcode eseguirà il progetto dalla cartella _DerivedData_. Questa cartella non è la stessa della cartella principale del progetto (dove si trova il file _Package.swift_). Questo significa che Vapor non sarà in grado di trovare file e cartelle come _.env_ o _Public_. 8 | 9 | Si capisce se questo sta accadendo se si vede il seguente avviso quando si esegue il progetto. 10 | 11 | ```fish 12 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 13 | ``` 14 | 15 | Per risolvere questo problema bisogna impostare una directory di lavoro personalizzata nello schema Xcode del progetto. 16 | 17 | Per prima cosa, modificare lo schema del progetto cliccando sul selettore dello schema vicino ai pulsanti play e stop. 18 | 19 | ![Xcode Scheme Area](../images/xcode-scheme-area.png) 20 | 21 | Selezionare _Edit Scheme..._ dal menu a tendina. 22 | 23 | ![Xcode Scheme Menu](../images/xcode-scheme-menu.png) 24 | 25 | Nell'editor dello schema, scegliere l'azione _App_ e la scheda _Options_. Selezionare _Use custom working directory_ e inserire il percorso alla cartella principale del progetto. 26 | 27 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 28 | 29 | Si può ottenere il percorso completo alla cartella principale del progetto eseguendo `pwd` da una finestra del terminale aperta lì. 30 | 31 | ```sh 32 | # ottenere il percorso di questa cartella 33 | pwd 34 | ``` 35 | 36 | Si dovrebbe vedere un output simile al seguente. 37 | 38 | ``` 39 | /percorso/al/progetto 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/getting-started/xcode.ja.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | このページでは、Xcode の使用に関するいくつかのヒントとテクニックを紹介します。異なる開発環境を使用している場合、このセクションはスキップしてもよいです。 4 | 5 | ## カスタムワーキングディレクトリ {#custom-working-directory} 6 | 7 | デフォルトでは、Xcode はあなたのプロジェクトを _DerivedData_ フォルダから実行します。このフォルダは、プロジェクトのルートフォルダ ( _Package.swift_ ファイルがある場所) とは異なります。これは、 Vapor が _.env_ や _Public_ のようなファイルやフォルダを見つけることができないことを意味します。 8 | 9 | アプリを実行するときに以下の警告が表示される場合、この問題が発生していることがわかります。 10 | 11 | ```fish 12 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 13 | ``` 14 | 15 | これを修正するには、プロジェクトの Xcode スキームでカスタムワーキングディレクトリを設定します。 16 | 17 | まず、プレイボタンとストップボタンの隣にあるスキームセレクタをクリックして、プロジェクトのスキームを編集します。 18 | 19 | ![Xcode Scheme Area](../images/xcode-scheme-area.png) 20 | 21 | ドロップダウンから _Edit Scheme..._ を選択します。 22 | 23 | ![Xcode Scheme Menu](../images/xcode-scheme-menu.png) 24 | 25 | スキームエディタで、_App_ アクションと _Options_ タブを選択します。_Use custom working directory_ をチェックし、プロジェクトのルートフォルダへのパスを入力します。 26 | 27 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 28 | 29 | プロジェクトのルートへのフルパスは、その場所で開いたターミナルウィンドウから `pwd` を実行することで取得できます。 30 | 31 | ```sh 32 | # get path to this folder 33 | pwd 34 | ``` 35 | 36 | 以下のような出力が表示されるはずです。 37 | 38 | ``` 39 | /path/to/project 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/getting-started/xcode.ko.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | 이 페이지에서는 Xcode를 사용하는 데 도움이 되는 팁에 대해 알려드립니다. 다른 개발 환경을 사용하는 경우 이 부분을 건너뛰어도 됩니다. 4 | 5 | ## Custom Working Directory 6 | 7 | 기본적으로 Xcode는 프로젝트를 DerivedData 폴더에서 실행합니다. 이 폴더는 프로젝트의 루트 폴더(즉, Package.swift 파일이 있는 곳)와 다른 폴더입니다. 따라서 Vapor는 .env 또는 _Public_과 같은 파일 및 폴더를 찾을 수 없게 됩니다. 8 | 9 | 앱을 실행할 때 다음 경고가 표시된다면 이런 상황이 발생하는 것입니다. 10 | 11 | ```fish 12 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 13 | ``` 14 | 15 | 이를 해결하기 위해 Xcode scheme에서 custom working directory를 설정하세요. 16 | 17 | 먼저, 재생 및 중지 버튼 옆에 있는 scheme selector를 클릭하여 프로젝트의 scheme을 편집하세요. 18 | 19 | ![Xcode Scheme Area](../images/xcode-scheme-area.png) 20 | 21 | Edit Scheme을 선택합니다. 22 | 23 | ![Xcode Scheme Menu](../images/xcode-scheme-menu.png) 24 | 25 | scheme editor에서 Options탭을 선택한 후 Use custom working directory를 클릭한 후 프로젝트 루트폴더 경로를 설정합니다. 26 | 27 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 28 | 29 | 프로젝트의 루트 폴더의 전체 경로를 얻으려면 해당 위치에서 터미널 창을 열고 `pwd`를 실행하세요. 30 | 31 | ```sh 32 | # get path to this folder 33 | pwd 34 | ``` 35 | 36 | 다음과 유사한 출력이 나타날 것입니다. 37 | 38 | ``` 39 | /path/to/project 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/getting-started/xcode.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | This page goes over some tips and tricks for using Xcode. If you use a different development environment, you can skip this. 4 | 5 | ## Custom Working Directory 6 | 7 | By default Xcode will run your project from the _DerivedData_ folder. This folder is not the same as your project's root folder (where your _Package.swift_ file is). This means that Vapor will not be able to find files and folders like _.env_ or _Public_. 8 | 9 | You can tell this is happening if you see the following warning when running your app. 10 | 11 | ```fish 12 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 13 | ``` 14 | 15 | To fix this, set a custom working directory in the Xcode scheme for your project. 16 | 17 | First, edit your project's scheme by clicking on the scheme selector by the play and stop buttons. 18 | 19 | ![Xcode Scheme Area](../images/xcode-scheme-area.png) 20 | 21 | Select _Edit Scheme..._ from the dropdown. 22 | 23 | ![Xcode Scheme Menu](../images/xcode-scheme-menu.png) 24 | 25 | In the scheme editor, choose the _App_ action and the _Options_ tab. Check _Use custom working directory_ and enter the path to your project's root folder. 26 | 27 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 28 | 29 | You can get the full path to your project's root by running `pwd` from a terminal window open there. 30 | 31 | ```sh 32 | # get path to this folder 33 | pwd 34 | ``` 35 | 36 | You should see output similar to the following. 37 | 38 | ``` 39 | /path/to/project 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/getting-started/xcode.nl.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | Deze pagina behandelt enkele tips en trucs voor het gebruik van Xcode. Als u een andere ontwikkelomgeving gebruikt, kunt u deze overslaan. 4 | 5 | ## Custom Working Directory 6 | 7 | Standaard zal Xcode uw project uitvoeren vanuit de _DerivedData_ map. Deze map is niet hetzelfde als de hoofdmap van uw project (waar uw _Package.swift_ bestand staat). Dit betekent dat Vapor niet in staat zal zijn om bestanden en mappen zoals _.env_ of _Public_ te vinden. 8 | 9 | U kunt zien dat dit gebeurt als u de volgende waarschuwing ziet wanneer u uw app uitvoert. 10 | 11 | ```fish 12 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 13 | ``` 14 | 15 | Om dit op te lossen, stelt u een aangepaste werkdirectory in het Xcode-schema in voor uw project. 16 | 17 | Bewerk eerst het schema van uw project door te klikken op de schema selector bij de play en stop knoppen. 18 | 19 | ![Xcode Scheme Area](../images/xcode-scheme-area.png) 20 | 21 | Selecteer _Edit Scheme..._ in de dropdown. 22 | 23 | ![Xcode Scheme Menu](../images/xcode-scheme-menu.png) 24 | 25 | Kies in de schema editor de actie _App_ en het tabblad _Options_. Vink _Use custom working directory_ aan en voer het pad in naar de hoofdmap van uw project. 26 | 27 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 28 | 29 | U kunt het volledige pad naar de root van uw project krijgen door `pwd` uit te voeren vanuit een terminal venster dat daar geopend is. 30 | 31 | ```sh 32 | # haal het pad naar deze map op 33 | pwd 34 | ``` 35 | 36 | U zou uitvoer moeten zien zoals hieronder. 37 | 38 | ``` 39 | /path/to/project 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/getting-started/xcode.pl.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | Ta strona zawiera wskazówki i porady dotyczące korzystania z Xcode. Jeśli korzystasz z innego środowiska programistycznego, możesz ją pominąć. 4 | 5 | ## Niestandardowy katalog roboczy 6 | 7 | Domyślnie Xcode uruchamia projekt z folderu _DerivedData_. Folder ten nie jest taki sam jak folder główny projektu (gdzie znajduje się plik _Package.swift_). Oznacza to, że Vapor nie będzie w stanie znaleźć plików i folderów takich jak _.env_ lub _Public_. 8 | 9 | Można to stwierdzić, jeśli podczas uruchamiania aplikacji pojawi się następujące ostrzeżenie. 10 | 11 | ```fish 12 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 13 | ``` 14 | 15 | Aby to naprawić, ustaw niestandardowy katalog roboczy w schemacie Xcode dla swojego projektu. 16 | 17 | Najpierw edytuj schemat projektu, klikając selektor schematu przy przyciskach odtwarzania i zatrzymania. 18 | 19 | ![Xcode Scheme Area](../images/xcode-scheme-area.png) 20 | 21 | Wybierz _Edit Scheme..._ z listy rozwijanej. 22 | 23 | ![Xcode Scheme Menu](../images/xcode-scheme-menu.png) 24 | 25 | W edytorze schematów wybierz akcję _App_ i zakładkę _Options_. Zaznacz opcję _Use custom working directory_ i wprowadź ścieżkę do folderu głównego projektu. 26 | 27 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 28 | 29 | Możesz uzyskać pełną ścieżkę do katalogu głównego projektu, uruchamiając `pwd` z otwartego tam okna terminala. 30 | 31 | ```sh 32 | # Uzyskaj ścieżkę do tego folderu 33 | pwd 34 | ``` 35 | 36 | Powinieneś zobaczyć dane wyjściowe podobne do poniższych. 37 | 38 | ``` 39 | /path/to/project 40 | ``` -------------------------------------------------------------------------------- /docs/getting-started/xcode.zh.md: -------------------------------------------------------------------------------- 1 | # Xcode 2 | 3 | 这篇将介绍一些使用 Xcode 的提示和技巧。如果你使用不同的开发环境,你可以跳过此篇。 4 | 5 | ## 自定义工作目录(Working directory) 6 | 7 | Xcode 将默认在 _DerivedData_ 目录运行项目。这与项目的根目录(你的 _Package.swift_ 文件所在的目录)不在同一个目录,这意味着 Vapor 将找不到像 _.env_ 或者 _Public_ 等一些文件和目录。 8 | 9 | 如果在运行应用程序时看到以下警告,你就可以知道这正在发生。 10 | 11 | ```fish 12 | [ WARNING ] No custom working directory set for this scheme, using /path/to/DerivedData/project-abcdef/Build/ 13 | ``` 14 | 15 | 要解决这个问题,你可以在 Xcode scheme 中为你的项目设置一个自定义的工作目录。 16 | 17 | 首先,编辑项目的 scheme。 18 | 19 | ![Xcode Scheme Area](../images/xcode-scheme-area.png) 20 | 21 | 在下拉框中选择 _Edit Scheme..._ 22 | 23 | ![Xcode Scheme Menu](../images/xcode-scheme-menu.png) 24 | 25 | 在 scheme 编辑器中,选择 _App_ action 以及 _Options_ tab 页。选中 _Use custom working directory_ 然后输入你项目根目录。 26 | 27 | ![Xcode Scheme Options](../images/xcode-scheme-options.png) 28 | 29 | 你可以在终端中运行 `pwd` 来获取你项目根目录的绝对目录。 30 | 31 | ```sh 32 | # 获取当前目录的路径 33 | pwd 34 | ``` 35 | 36 | 你应该能看见类似下面的输出。 37 | 38 | ``` 39 | /path/to/project 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/images/digital-ocean-create-droplet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/digital-ocean-create-droplet.png -------------------------------------------------------------------------------- /docs/images/digital-ocean-distributions-ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/digital-ocean-distributions-ubuntu.png -------------------------------------------------------------------------------- /docs/images/digital-ocean-droplet-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/digital-ocean-droplet-list.png -------------------------------------------------------------------------------- /docs/images/github-link-issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/github-link-issue.png -------------------------------------------------------------------------------- /docs/images/swift-download-ubuntu-copy-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/swift-download-ubuntu-copy-link.png -------------------------------------------------------------------------------- /docs/images/vapor-splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/vapor-splash.png -------------------------------------------------------------------------------- /docs/images/xcode-mac-app-store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/xcode-mac-app-store.png -------------------------------------------------------------------------------- /docs/images/xcode-scheme-area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/xcode-scheme-area.png -------------------------------------------------------------------------------- /docs/images/xcode-scheme-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/xcode-scheme-menu.png -------------------------------------------------------------------------------- /docs/images/xcode-scheme-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vapor/docs/22de82072bdb733ce51de4d6d47dc0481cbd0a59/docs/images/xcode-scheme-options.png -------------------------------------------------------------------------------- /docs/index.de.md: -------------------------------------------------------------------------------- 1 | # Willkommen 2 | 3 | Willkommen zur Dokumentation von Vapor! Vapor ist ein Web-Framework für Swift, mit das du Webseiten, ganze Webserver oder APIs schreiben kannst. Vapor selbst ist in Swift geschrieben, welche eine moderne, leistungsstarke und sichere Sprache ist und die gegenüber anderen Serversprachen eine Vielzahl von Vorteilen bietet. 4 | 5 | ## Einstieg 6 | 7 | Für die Installation, folge den Anweisungen im Abschnitt [Installation → macOS](install/macos.md). Nach der Installation, folge den Anweisungen [Erste Schritte → Hello, world](getting-started/hello-world.md) um deine erste Vapor-Anwendungen zu erstellen. 8 | 9 | ## Hilfen 10 | 11 | Mehr Informationen zum Web-Framework findest du unter anderem hier: 12 | 13 | | name | description | link | 14 | |----------------|--------------------------------------------------------------|------------------------------------------------------------------| 15 | | Vapor Discord | Tausche dich mit anderen Mitgliedern der Vapor-Community aus.| [visit →](https://vapor.team) | 16 | | API docs | Auto-generierte Dokumentation zu Vapor. | [visit →](https://api.vapor.codes) | 17 | | Stack Overflow | Stelle Fragen oder lese Antworten zu Vapor auf Stackoverflow.| [visit →](https://stackoverflow.com/questions/tagged/vapor) | 18 | | Swift Forums | Beiträge zu Vapor im offiziellen Swift-Forum. | [visit →](https://forums.swift.org/c/related-projects/vapor)| 19 | | Source Code | Der ganze Quellcode von Vapor auf Github. | [visit →](https://github.com/vapor/vapor) | 20 | | GitHub Issues | Melde Fehler oder reiche deine Ideen auf Github ein. | [visit →](https://github.com/vapor/vapor/issues) | 21 | 22 | ## Altversionen 23 | 24 | Die Dokumentationen zu älteren Versionen von Vapor findest du unter [https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/). 25 | 26 | ## Authoren 27 | 28 | Das Vapor-Kernteam und viele weitere Mitglieder der Vapor-Community. 29 | -------------------------------------------------------------------------------- /docs/index.es.md: -------------------------------------------------------------------------------- 1 | ¡Bienvenido a la documentación de Vapor! Vapor es un framework de desarrollo web para Swift, que permite escribir backends, APIs de aplicaciones web y servidores HTTP en Swift. Vapor está escrito en Swift, que es un lenguaje moderno, potente y seguro, el cual brinda una serie de beneficios sobre los lenguajes de servidor más tradicionales. 2 | 3 | ## Comenzando 4 | 5 | Si es la primera vez que utiliza Vapor, diríjase a [Instalación → macOS](install/macos.md) para instalar Swift y Vapor. 6 | 7 | Una vez que haya instalado Vapor, consulte [Comenzando → Hola, mundo](getting-started/hello-world.md) para crear su primera aplicación de Vapor. 8 | 9 | ## Otras Fuentes 10 | 11 | Aquí hay otros excelentes lugares para encontrar información sobre Vapor. 12 | 13 | | nombre | descripción | enlace | 14 | |----------------------|---------------------------------------------------------------------------|---------------------------------------------------------------------| 15 | | Discord de Vapor | Habla con miles de desarrolladores de Vapor. | [visitar →](https://vapor.team) | 16 | | Documentación de API | Documentación generada automáticamente a partir de comentarios de código. | [visitar →](https://api.vapor.codes) | 17 | | Stack Overflow | Haz y responde preguntas con la etiqueta `vapor`. | [visitar →](https://stackoverflow.com/questions/tagged/vapor) | 18 | | Foros de Swift | Publique en la sección de Vapor de los foros de Swift.org | [visitar →](https://forums.swift.org/c/related-projects/vapor) | 19 | | Código Fuente | Aprende cómo funciona Vapor por dentro. | [visitar →](https://github.com/vapor/vapor) | 20 | | GitHub Issues | Informa errores o solicita nuevas funcionalidades en GitHub. | [visitar →](https://github.com/vapor/vapor/issues) | 21 | 22 | ## Documentación Anterior 23 | 24 | La documentación de las versiones obsoletas de Vapor que ahora se encuentran en su fin de vida útil, se puede encontrar en [https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/). 25 | 26 | ## Autores 27 | 28 | El Vapor Core Team, y los cientos de miembros de la comunidad Vapor. 29 | -------------------------------------------------------------------------------- /docs/index.fr.md: -------------------------------------------------------------------------------- 1 | Bienvenue sur la documentation de Vapor ! Vapor est un framework web pour Swift, qui vous autorise à développer des backends, des web apps API et des serveurs HTTP en Swift, qui est un langage moderne, puissant et sécurisé qui donne de nombreux bénéfices au-dessus le plus de langages de serveurs traditionnels. 2 | 3 | ## Commencer 4 | 5 | Si c'est la première fois que vous utiliser Vapor, naviguer vers [Installer → macOS](install/macos.md) pour installer Swift et Vapor. 6 | 7 | Une fois que Vapor à été installé, regargez [Commencer → Bonjour, monde](getting-started/hello-world.md) pour créer votre première app Vapor ! 8 | 9 | ## Autres sources 10 | 11 | Ici vous avez quelques autres bons endroits où trouver des informations sur Vapor. 12 | 13 | | name | description | link | 14 | | -------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------- | 15 | | Vapor Discord | Chatter avec des milliers de developpeurs Vapor. | [visiter →](https://vapor.team) | 16 | | API docs | Documentation auto-générée à partir des commentaires de code. | [visiter →](https://api.vapor.codes) | 17 | | Stack Overflow | Demander et réponder à des question avec le tag `vapor`. | [visiter →](https://stackoverflow.com/questions/tagged/vapor) | 18 | | Swift Forums | Poster dans la section de Vapor sur les forums de Swift.org. | [visiter →](https://forums.swift.org/c/related-projects/vapor) | 19 | | Source Code | Apprendre comment Vapor fonctionne sous le capot. | [visiter →](https://github.com/vapor/vapor) | 20 | | GitHub Issues | Signaler des bugs ou demander des fonctionnalitées sur GitHub. | [visiter →](https://github.com/vapor/vapor/issues) | 21 | 22 | ## Ancienne Documentation 23 | 24 | Documentation pour les versions dépréciées de Vapor qui sont maintenant en fin-de-vie peuvent être trouvées sur [https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/). 25 | 26 | ## Auteurs 27 | 28 | La Vapor Core Team, et les centaines de membres de la communauté de Vapor. 29 | -------------------------------------------------------------------------------- /docs/index.it.md: -------------------------------------------------------------------------------- 1 | Benvenuto nella documentazione di Vapor! Vapor è un framework web per Swift. Permette di creare backend, applicazioni web, API e server HTTP in Swift. Vapor è scritto in Swift, un linguaggio moderno, potente e sicuro che fornisce diversi benefici rispetto a linguaggi lato server tradizionali. 2 | 3 | ## Inizio 4 | 5 | Se è la prima volta che utilizzi Vapor, vai su [Installazione → macOS](install/macos.md) per installare Swift e Vapor. 6 | 7 | Una volta installato Vapor, date un'occhiata a [Inizio → Ciao, mondo](getting-started/hello-world.md) per creare la tua prima applicazione Vapor! 8 | 9 | ## Altre Fonti 10 | 11 | Ecco alcuni altri ottimi posti dove trovare informazioni su Vapor. 12 | 13 | | nome | descrizione | link | 14 | |----------------|--------------------------------------------------|-------------------------------------------------------------------| 15 | | Discord Vapor | Chiacchiera con migliaia di sviluppatori Vapor. | [visita →](https://vapor.team) | 16 | | Documentazione API | Documentazione auto-generata dai commenti nel codice. | [visita →](https://api.vapor.codes) | 17 | | Stack Overflow | Poni e rispondi a domande con il tag `vapor`. | [visita →](https://stackoverflow.com/questions/tagged/vapor) | 18 | | Swift Forums | Pubblica nella sezione Vapor dei forum di Swift.org. | [visita →](https://forums.swift.org/c/related-projects/vapor) | 19 | | Codice Sorgente | Scopri come funziona Vapor sotto il cofano. | [visita →](https://github.com/vapor/vapor) | 20 | | Issues di GitHub | Segnala bug o richiedi funzionalità su GitHub. | [visita →](https://github.com/vapor/vapor/issues) | 21 | 22 | ## Documentazione Obsoleta 23 | 24 | La documentazione per le versioni deprecate di Vapor che non sono più manutenute è su [https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/). 25 | -------------------------------------------------------------------------------- /docs/index.ja.md: -------------------------------------------------------------------------------- 1 | Vapor ドキュメントへようこそ! Vapor は Swift の Web フレームワークで、Swift でバックエンド、ウェブアプリの API、HTTP サーバーを書くことができます。 Vapor は Swift で書いており、それは伝統的なサーバー言語よりも多くの利点を提供するモダンで強力で安全な言語です。 2 | 3 | ## はじめに {#getting-started} 4 | 5 | もし、Vapor を使うのが初めてならば、Swift と Vapor をインストールするために[インストール → macOS](install/macos.md)に進んでください。 6 | 7 | Vapor をインストールしたら、初めての Vapor アプリを作成するために[はじめに → Hello, world](getting-started/hello-world.md)をチェックしてください! 8 | 9 | 10 | ## その他の情報源 {#other-sources} 11 | 12 | Vapor に関する情報を見つけるには、他にも素晴らしい場所があります。 13 | 14 | | 名前 | 説明 | リンク | 15 | |----------------|--------------------------------------------------|-------------------------------------------------------------------| 16 | | Vapor Discord | 数千人の Vapor 開発者とチャットします | [visit →](https://vapor.team) | 17 | | API ドキュメント | コードコメントから自動生成されたドキュメント | [visit →](https://api.vapor.codes) | 18 | | Stack Overflow | `vapor` タグで質問し回答します | [visit →](https://stackoverflow.com/questions/tagged/vapor) | 19 | | Swift フォーラム | Swift.org フォーラムの Vapor セクションに投稿します | [visit →](https://forums.swift.org/c/related-projects/vapor) | 20 | | ソースコード | Vapor の内部での動作を学びます | [visit →](https://github.com/vapor/vapor) | 21 | | GitHub Issues | GitHub でバグを報告したり、機能をリクエストします | [visit →](https://github.com/vapor/vapor/issues) | 22 | 23 | ## 旧ドキュメント {#old-documentation} 24 | 25 | 廃止されたバージョンの Vapor ドキュメントは、[https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/)で見ることができます。 26 | 27 | ## 著者 {#authors} 28 | 29 | Vapor コアチーム、および Vapor コミュニティの数百人のメンバー。 30 | -------------------------------------------------------------------------------- /docs/index.ko.md: -------------------------------------------------------------------------------- 1 | Vapor 문서에 오신 걸 환영합니다! Vapor는 Swift를 사용하여 백엔드, 웹 앱 API 및 HTTP 서버를 작성할 수 있는 웹 프레임워크입니다. Vapor은 현대적이고 강력하며 안전한 언어인 Swift로 작성되어 기존의 서버 언어에 비해 여러 가지 이점을 제공합니다. 2 | 3 | ## 시작하기 4 | 5 | Vapor를 처음 사용하시는 경우, [설치 → macOS](install/macos.ko.md) 로 이동하여 Swift와 Vapor를 설치하세요. 6 | 7 | Vapor를 설치한 후에는, [시작하기 → Hello, world](getting-started/hello-world.ko.md)를 확인하여 첫 번째 Vapor 앱을 생성해보세요! 8 | 9 | ## 추가 정보 10 | 11 | 다른 Vapor에 대한 정보를 찾을 수 있는 좋은 자료들이 몇 군데 있습니다. 다음은 몇 가지 예시입니다. 12 | 13 | | 이름 | 설명 | 링크 | 14 | |----------------|--------------------------------------------------|-------------------------------------------------------------------| 15 | | Vapor 디스코드 | Vapor 개발자들과 소통을 하려면 디스코드를 이용하세요. | [visit →](https://vapor.team) | 16 | | API 문서 | 자동 생성된 코드 주석에서 생성된 문서를 참조하세요. | [visit →](https://api.vapor.codes) | 17 | | Stack Overflow | `vapor` 태그를 사용하여 질문하고 답변을 받으세요. | [visit →](https://stackoverflow.com/questions/tagged/vapor) | 18 | | Swift 포럼 | Swift.org 포럼의 Vapor 섹션에 게시하세요. | [visit →](https://forums.swift.org/c/related-projects/vapor) | 19 | | 소스 코드 | Vapor 내부 작동 방식을 배워보세요. | [visit →](https://github.com/vapor/vapor) | 20 | | 깃허브 이슈 | GitHub에서 버그를 보고하거나 기능을 요청하세요. | [visit →](https://github.com/vapor/vapor/issues) | 21 | 22 | ## 이전 버전 문서 23 | 24 | 더 이상 지원되지 않는 Vapor의 이전 버전에 대한 문서는 [https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/)에서 확인할 수 있습니다. 25 | 26 | ## 작성자 27 | 28 | Vapor Core 팀 및 Vapor 커뮤니티의 수백 명의 구성원들이 기여하였습니다. 29 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | Welcome to the Vapor Documentation! Vapor is a web framework for Swift, allowing you to write backends, web apps APIs and HTTP servers in Swift. Vapor is written in Swift, which is a modern, powerful and safe language providing a number of benefits over the more traditional server languages. 2 | 3 | ## Getting Started 4 | 5 | If this is your first time using Vapor, head to [Install → macOS](install/macos.md) to install Swift and Vapor. 6 | 7 | Once you have Vapor installed, check out [Getting Started → Hello, world](getting-started/hello-world.md) to create your first Vapor app! 8 | 9 | ## Other Sources 10 | 11 | Here are some other great places to find information about Vapor. 12 | 13 | | name | description | link | 14 | |----------------|--------------------------------------------------|-------------------------------------------------------------------| 15 | | Vapor Discord | Chat with thousands of Vapor developers. | [visit →](https://vapor.team) | 16 | | API docs | Auto-generated documentation from code comments. | [visit →](https://api.vapor.codes) | 17 | | Stack Overflow | Ask and answer questions with the `vapor` tag. | [visit →](https://stackoverflow.com/questions/tagged/vapor) | 18 | | Swift Forums | Post in Vapor's section of the Swift.org forums. | [visit →](https://forums.swift.org/c/related-projects/vapor) | 19 | | Source Code | Learn how Vapor works under the hood. | [visit →](https://github.com/vapor/vapor) | 20 | | GitHub Issues | Report bugs or request features on GitHub. | [visit →](https://github.com/vapor/vapor/issues) | 21 | 22 | ## Old Documentation 23 | 24 | Documentation for deprecated versions of Vapor that are now end-of-life can be found at [https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/). 25 | 26 | ## Authors 27 | 28 | The Vapor Core Team, and the hundreds of members of the Vapor community. 29 | -------------------------------------------------------------------------------- /docs/index.nl.md: -------------------------------------------------------------------------------- 1 | Welkom bij de Vapor Documentatie! Vapor is een web framework voor Swift, dat u toelaat om back-ends, web apps APIs en HTTP servers te schrijven in Swift. Vapor is geschreven in Swift, wat een moderne, krachtige en veilige taal die verscheidene voordelen bied tegenover de meer traditionele server talen. 2 | 3 | ## Eerste stappen 4 | 5 | Als dit je eerste keer is dat je Vapor gebruikt, ga naar [Install → macOS](install/macos.md) om Swift en Vapor te installeren. 6 | 7 | Wanneer dat je Vapor hebt geinstalleerd, bekijk dan [Getting Started → Hello, world](getting-started/hello-world.md) om je eerste Vapor app te maken. 8 | 9 | ## Andere bronnen 10 | 11 | Hier zijn een paar andere geweldige plaatsen om meer informatie te vinden over Vapor 12 | 13 | | naam | beschrijving | link | 14 | |----------------|--------------------------------------------------|-----------------------------------------------------------------| 15 | | Vapor Discord | Praat met duizenden Vapor developers. | [visit →](https://vapor.team) | 16 | | API docs | Auto-generated documentation from code comments. | [visit →](https://api.vapor.codes) | 17 | | Stack Overflow | Vraag en beantwoord vragen met de `vapor` tag. | [visit →](https://stackoverflow.com/questions/tagged/vapor) | 18 | | Swift Forums | Post in de Vapor sectie van de Swift.org forums. | [visit →](https://forums.swift.org/c/related-projects/vapor) | 19 | | Source Code | Leer hoe Vapor werkt onder de motorkap. | [visit →](https://github.com/vapor/vapor) | 20 | | GitHub Issues | Meld fouten of verzoek functies aan op GitHub. | [visit →](https://github.com/vapor/vapor/issues) | 21 | 22 | 23 | ## Oude documentatie 24 | 25 | Documentatie voor verouderde versies van Vapor die nu op hun levenseinde zitten kunnen gevonden worden op [https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/). 26 | 27 | ## Auteurs 28 | 29 | Het Vapor Core Team, en de honderden leden van de Vapor gemeenschap. 30 | -------------------------------------------------------------------------------- /docs/index.pl.md: -------------------------------------------------------------------------------- 1 | Witaj w dokumentacji Vapor! Vapor jest frameworkiem do tworzenia aplikacji internetowych z wykorzystaniem języka Swift. Pozwala na pisanie serwisów backendowych, API internetowych i serwerów HTTP w Swifcie. 2 | 3 | ## Jak zacząć 4 | 5 | Jeśli to jest twój pierwszy raz z Vapor, kieruj się do [Instalacja → macOS](install/macos.md) aby, zainstalować Swift i Vapor. 6 | Kiedy już zainstalujesz Vapor, sprawdź [Jak zacząć → Witaj, świecie](getting-started/hello-world.md) aby stworzyć twoja pierwsza aplikacje z użyciem Vapor! 7 | 8 | ## Inne źródła 9 | 10 | Tutaj znajdziesz inne świetne źródła informacji o Vapor. 11 | 12 | | nazwa | opis | link | 13 | |----------------|--------------------------------------------------|-------------------------------------------------------------------| 14 | | Vapor Discord | Rozmawiaj z tysiącami deweloperów. | [zobacz →](https://vapor.team) | 15 | | Dokumentacja API | Samo generująca się dokumentacja z komentarzy do kodu. | [zobacz →](https://api.vapor.codes) | 16 | | Stack Overflow | Zadawaj i odpowiadaj na pytania z tagiem `vapor`. | [zobacz →](https://stackoverflow.com/questions/tagged/vapor) | 17 | | Forum Swift | Zapostuj w sekcji Vapor na forum Swift.org. | [zobacz →](https://forums.swift.org/c/related-projects/vapor) | 18 | | Kod źródłowy | Naucz się jak Vapor działa pod maską. | [zobacz →](https://github.com/vapor/vapor) | 19 | | GitHub Issues | Zgłaszaj błędy oraz prośby na GitHub. | [zobacz →](https://github.com/vapor/vapor/issues) | 20 | 21 | ## Stara dokumentacja 22 | 23 | Dokumentacja dla wcześniejszych wersji Vapor, które osiągnęły swój koniec życia można znaleźć na [https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/). 24 | 25 | ## Autorzy 26 | 27 | The Vapor Core Team, oraz setki członków społeczności wokoło Vapor. 28 | -------------------------------------------------------------------------------- /docs/index.zh.md: -------------------------------------------------------------------------------- 1 | 欢迎使用 [Vapor](https://vapor.codes/)!Vapor 是基于 [Swift](https://www.swift.org/) 编程语言而开发的最流行的 Web 网络框架,这是一种更先进、强大且类型安全的编程语言。通过 Vapor,你可以使用 Swift 编写后端、Web 应用 API 或 HTTP 服务,与传统的服务器语言相比具有许多优点。 2 | 3 | ## 开始 4 | 5 | 如果你是第一次使用 Vapor,请前往 [安装 → macOS](install/macos.md) 安装 Swift 和 Vapor 开发环境。 6 | 7 | Vapor 安装完成后,请查看 [开始 → 你好,世界](getting-started/hello-world.md) 示例,以创建你的第一个 Vapor 应用程序! 8 | 9 | ## 其他资源 10 | 11 | 这里是其他一些有关 Vapor 框架的内容,以供学习与交流。 12 | 13 | | 名称 | 描述 | 链接 | 14 | |----------------|--------------------------------------------------|-----------------------------------------------------------------| 15 | | Vapor Discord | 与数千名 Vapor 开发人员交流。 | [访问 →](http://vapor.team) | 16 | | API docs | 通过代码注释自动生成的文档。 | [访问 →](http://api.vapor.codes) | 17 | | Stack Overflow | 使用 `Vapor` 标签提问和回答相关问题。 | [访问 →](http://stackoverflow.com/questions/tagged/vapor) | 18 | | Swift Forums |在 Swift.org 论坛的 Vapor 专题发布。 | [访问 →](https://forums.swift.org/c/related-projects/vapor) | 19 | | Source Code | 了解 Vapor 的工作原理。 | [访问 →](https://github.com/vapor/vapor) | 20 | | GitHub Issues | 在 GitHub 上报告错误或提交功能。 | [访问 →](https://github.com/vapor/vapor/issues) | 21 | 22 | ## 旧版文档 23 | 24 | 旧版文档已废弃,如有需要可在此查看:[https://legacy.docs.vapor.codes/](https://legacy.docs.vapor.codes/)。 25 | 26 | ## 作者 27 | 28 | Vapor 核心团队以及 Vapor 社区的数百名成员。 29 | -------------------------------------------------------------------------------- /docs/install/linux.ko.md: -------------------------------------------------------------------------------- 1 | # 리눅스에 Vapor 설치하기 2 | 3 | Vapor를 사용하려면 Swift 5.9 이상이 필요합니다. 리눅스에 Swift를 설치하려면, [Swift.org](https://swift.org/download/)에서 제공하는 툴체인을 사용하여 설치할 수 있습니다. 4 | 5 | ## 지원되는 배포판 및 버전 6 | 7 | Vapor는 Swift 5.9 이상을 지원하는 Linux 배포판의 동일한 버전을 지원합니다. 8 | 9 | !!! 노트 10 | 아래에 나열된 지원되는 버전은 언제든지 최신 정보가 아닐 수 있습니다. 공식적으로 지원되는 운영 체제는 [Swift Releases](https://swift.org/download/#releases) 페이지에서 확인할 수 있습니다. 11 | 12 | |배포판|버전|Swift 버전| 13 | |-|-|-| 14 | |Ubuntu|20.04|>= 5.9| 15 | |Fedora|>= 30|>= 5.9| 16 | |CentOS|8|>= 5.9| 17 | |Amazon Linux|2|>= 5.9| 18 | 19 | 공식적으로 지원되지 않는 Linux 배포판은 소스 코드를 컴파일하여 Swift를 실행할 수 있지만, Vapor는 안정성을 보장할 수 없습니다. Swift의 컴파일 방법에 대해서는 [Swift 저장소](https://github.com/apple/swift#getting-started)에서 자세히 알아보세요. 20 | 21 | ## Swift 설치하기 22 | 23 | Swift를 Linux에 설치하는 방법은 Swift.org의 [다운로드 및 사용하기](https://swift.org/download/#using-downloads) 가이드를 참조하세요. 24 | 25 | ### Fedora 26 | 27 | Fedora 사용자는 다음 명령어를 사용하여 Swift를 설치할 수 있습니다. 28 | 29 | ```sh 30 | sudo dnf install swift-lang 31 | ``` 32 | 33 | Fedora 30을 사용하는 경우, Swift 5.9 이상 버전을 얻기 위해 EPEL 8을 추가해야 합니다. 34 | 35 | ## Docker 36 | 37 | Swift의 공식 Docker 이미지를 사용하여 미리 컴파일된 컴파일러를 사용할 수도 있습니다. [Swift's Docker Hub](https://hub.docker.com/_/swift)에서 더 자세한 내용을 알아보세요. 38 | 39 | ## Toolbox 설치하기 40 | 41 | 이제 Swift가 설치되었으므로 [Vapor Toolbox](https://github.com/vapor/toolbox)를 설치해봅시다. 이 CLI 도구는 Vapor를 사용하는 데 필수적이지는 않지만, 유용한 유틸리티를 제공합니다. 42 | 43 | Linux에서는 Toolbox를 소스 코드로부터 빌드해야 합니다. GitHub에서 toolbox의 releases를 확인하여 최신 버전을 찾아보세요. 44 | 45 | ```sh 46 | git clone https://github.com/vapor/toolbox.git 47 | cd toolbox 48 | git checkout 49 | make install 50 | ``` 51 | 52 | Toolbox 설치가 성공적으로 이루어졌는지 확인하기 위해 도움말을 출력해보세요. 53 | 54 | ```sh 55 | vapor --help 56 | ``` 57 | 58 | 사용 가능한 명령어 목록이 표시되어야 합니다. 59 | 60 | ## 다음 단계 61 | 62 | Swift를 설치한 후 [시작하기 → Hello, world](../getting-started/hello-world.ko.md)에서 첫 번째 앱을 생성하세요. 63 | -------------------------------------------------------------------------------- /docs/install/linux.nl.md: -------------------------------------------------------------------------------- 1 | # Installeren op Linux 2 | 3 | Om Vapor te gebruiken op Linux, zal je Swift 5.9 of hoger nodig hebben. Dit kan geïnstalleerd worden met de toolchains te vinden op [Swift.org](https://swift.org/download/). 4 | 5 | ## Ondersteunde distributies en versies 6 | 7 | Vapor ondersteund dezelfde versies van Linux distributies die Swift 5.9 of hogere versies ook ondersteunen. 8 | 9 | !!! Opmerking 10 | The ondersteunde versies hieronder kunnen op elke moment verouderd zijn. Je kan zien welke besturingssystemen officiele ondersteuning krijgen op de [Swift Releases](https://swift.org/download/#releases/) pagina. 11 | 12 | |Distribution|Version|Swift Version| 13 | |-|-|-| 14 | |Ubuntu|20.04|>= 5.9| 15 | |Fedora|>= 30|>= 5.9| 16 | |CentOS|8|>= 5.9| 17 | |Amazon Linux|2|>= 5.9| 18 | 19 | Linux distributies die niet officieel ondersteund zijn kunnen mogelijks ook Swift uitvoeren door de broncode te compileren, maar Vapor kan geen stabiliteit garanderen. Meer informatie over het compileren van Swift kan gevonden worden op de [Swift repo](https://github.com/apple/swift#getting-started). 20 | 21 | ## Installeer Swift 22 | 23 | Bezoek Swift.org's [Using Downlaods](https://swift.org/download/#using-downloads) gids voor instructies over het installeren van Swift op Linux. 24 | 25 | ### Fedora 26 | 27 | Fedora gebruikers kunnen eenvoudig het volgende commando gebruiken om Swift te installeren: 28 | 29 | ```sh 30 | sudo dnf install swift-lang 31 | ``` 32 | 33 | Als je Fedore 30 gebruikt, dan zal je EPEL 8 moeten toevoegen om Swift 5.9 of nieuwere versies te krijgen. 34 | 35 | ## Docker 36 | 37 | Je kan ook de officiële Docker images van Swift gebruiken, die met de compiler vooraf geïnstalleerd komen. Meer informatie op [Swift's Docker Hub](https://hub.docker.com/_/swift). 38 | 39 | ## Installeer de Toolbox 40 | 41 | Nu dat je Swift hebt geïnstalleerd, laten we [Vapor's Toolbox](https://github.com/vapor/toolbox) installeren. Deze CLI tool is niet noodzakelijk om Vapor te gebruiken, maar het bevat wel handige hulpprogramma's. 42 | 43 | Op Linux zal je de toolbox moeten bouwen vanaf de bron. Bekijk de releases van de toolbox op GitHub om de nieuwste versie te vinden. 44 | 45 | ```sh 46 | git clone https://github.com/vapor/toolbox.git 47 | cd toolbox 48 | git checkout 49 | make install 50 | ``` 51 | 52 | Controleer of de installatie is gelukt door het help commando te gebruiken. 53 | 54 | ```sh 55 | vapor --help 56 | ``` 57 | 58 | Je zou een lijst met beschikbare commando's moeten zien. 59 | 60 | ## Next 61 | 62 | Nadat je Swift hebt geïnstalleerd, maak je eerste applicatie in [Aan De Slag → Hallo, wereld](../getting-started/hello-world.md). 63 | -------------------------------------------------------------------------------- /docs/install/linux.pl.md: -------------------------------------------------------------------------------- 1 | # Zainstaluj na Linux 2 | 3 | Aby używać Vapor, będziesz potrzebować Swifta w wersji 5.9 lub wyższej. Możesz go zainstalować używając jednego z plików instalacyjnych na [Swift.org](https://swift.org/download/). 4 | 5 | ## Wspierane dystrybucje i wersje 6 | 7 | Vapor wspiera te same wersje dystrybucji Linuxa jak wersja 5.9 lub nowsza Swifta. 8 | 9 | !!! note 10 | Wspierane wersje wypisane poniżej mogą być przeterminowane w momencie gdy to czytasz. Możesz zobaczyć które systemy operacyjne czy dystrybucje są wpierane na stronie [Swift Releases](https://swift.org/download/#releases). 11 | 12 | |Dystrybucja|Wersja|Wersja Swift| 13 | |-|-|-| 14 | |Ubuntu|20.04|>= 5.9| 15 | |Fedora|>= 30|>= 5.9| 16 | |CentOS|8|>= 5.9| 17 | |Amazon Linux|2|>= 5.9| 18 | 19 | Dystrybucje Linuxa które nie są oficjalnie wspierane mogą również użyć Swifta po przez kompilacje kodu źródłowego, lecz Vapor nie daje gwarancji stabilności. Dowiedz się więcej o kompilacji Swifta z oficjalnego repozytorium [Swift repo](https://github.com/apple/swift#getting-started). 20 | 21 | ## Instalacja Swifta 22 | 23 | Wejdź na Swift.org i użyj instrukcji pod adresem [Using Downloads](https://swift.org/download/#using-downloads) aby zainstalować Swifta na Linux. 24 | 25 | ### Fedora 26 | 27 | Użytkownicy Fedory mogę po prostu użyć następującej komendy aby zainstalować Swifta: 28 | 29 | ```sh 30 | sudo dnf install swift-lang 31 | ``` 32 | 33 | Jeśli używasz Fedora 30, będziesz musiał dodać EPEL 8, aby używać Swifta 5.9 lub nowszego. 34 | 35 | ## Docker 36 | 37 | Możesz również użyć oficjalnego obrazu Docker Swifta, który ma już preinstalowany kompilator. Dowiedz się więcej na [Swift's Docker Hub](https://hub.docker.com/_/swift). 38 | 39 | ## Zainstaluj Toolbox 40 | 41 | Teraz gdy masz już zainstalowanego Swifta, zainstalujmy [Vapor Toolbox](https://github.com/vapor/toolbox). Jest to narzędzie CLI (z ang. Command Line Interface), które nie jest potrzebne by używać Vapora, natomiast jest wyposażone w przydatne usprawnienia takie jak kreator nowego projektu. 42 | 43 | Na Linux, musisz zbudować toolbox z źródła. Odwiedź [wydania](https://github.com/vapor/toolbox/releases) toolboxu na Github aby znaleźć najnowsza wersję. 44 | 45 | ```sh 46 | git clone https://github.com/vapor/toolbox.git 47 | cd toolbox 48 | git checkout 49 | make install 50 | ``` 51 | 52 | Sprawdź dwa razy czy instalacja przeszła poprawnie po przez wyświetlenie pomocy. 53 | 54 | ```sh 55 | vapor --help 56 | ``` 57 | 58 | Powinna być widoczna lista dostępnych komend. 59 | 60 | ## Następnie 61 | 62 | Kiedy już udało Ci się zainstalować Swifta, stwórz swoja pierwszą aplikacje w sekcji [Pierwsze kroki → Witaj, świecie](../getting-started/hello-world.md). 63 | -------------------------------------------------------------------------------- /docs/install/linux.zh.md: -------------------------------------------------------------------------------- 1 | 2 | # 在 Linux 上面安装 3 | 4 | 你需要 Swift 5.9 或更高版本来使用 Vapor。你可以使用 Swift Server Workgroup 提供的 CLI 工具 [Swiftly](https://swiftlang.github.io/swiftly/) 来安装(推荐),也可以通过 [Swift.org](https://swift.org/download/) 上面的工具链来安装。 5 | 6 | ## 支持的发行版和版本 7 | 8 | Vapor 支持的发行版的版本与 Swift 5.9 或更新版本支持的 Linux 发行版的版本相同。请参阅[官方支持页面](https://www.swift.org/platform-support/)查找有关官方支持的操作系统的最新信息。 9 | 10 | 不受官方支持的 Linux 发行版也可以通过编译源代码来运行 Swift,但是 Vapor 不能保证其稳定性。可以在 [Swift repo](https://github.com/apple/swift#getting-started) 学习更多关于编译 Swift 的信息。 11 | 12 | ## 安装 Swift 13 | 14 | ### 使用 Swiftly CLI 工具自动安装(推荐) 15 | 16 | 访问 [Swifty 网站](https://swiftlang.github.io/swiftly/)获取在Linux上安装 Swiftly 和 Swift 的说明。之后,使用以下命令安装 Swift: 17 | 18 | #### 基本使用 19 | 20 | ```sh 21 | $ swiftly install latest 22 | 23 | Fetching the latest stable Swift release... 24 | Installing Swift 5.9.1 25 | Downloaded 488.5 MiB of 488.5 MiB 26 | Extracting toolchain... 27 | Swift 5.9.1 installed successfully! 28 | 29 | $ swift --version 30 | 31 | Swift version 5.9.1 (swift-5.9.1-RELEASE) 32 | Target: x86_64-unknown-linux-gnu 33 | ``` 34 | 35 | ### 使用 toolchain 手动安装 36 | 37 | 访问 Swift.org 的 [Using Downloads](https://swift.org/download/#using-downloads) 手册来学习如何在 Linux 安装 Swift。 38 | 39 | ### Fedora 40 | 41 | Fedora 用户可以简单的通过下面的命令来安装 Swift: 42 | 43 | ```sh 44 | sudo dnf install swift-lang 45 | ``` 46 | 47 | 如果你正在使用 Fedora 35,你需要添加添加 EPEL 8 来获取 Swift 5.9 或更新的版本。 48 | 49 | 50 | ## Docker 51 | 52 | 你也可以使用预装了编译器的 Swift 官方 Docker 镜像,可以在 [Swift's Docker Hub](https://hub.docker.com/_/swift) 了解更多。 53 | 54 | ## 安装工具箱(Install Toolbox) 55 | 56 | 现在你已经安装了 Swift,让我们安装 [Vapor Toolbox](https://github.com/vapor/toolbox)。使用 Vapor 不是必须要使用此 CLI 工具,但它包含有用的实用程序。 57 | 58 | 在 Linux 系统上,你需要通过源码来编译 toolbox,在 Github 上查看 toolbox 的 releases 来获取最新版本。 59 | 60 | ```sh 61 | git clone https://github.com/vapor/toolbox.git 62 | cd toolbox 63 | git checkout 64 | make install 65 | ``` 66 | 67 | 通过打印信息来再次确认是否已经安装成功。 68 | 69 | ```sh 70 | vapor --help 71 | ``` 72 | 73 | 你应该能看见可用命令的列表。 74 | 75 | ## 下一步 76 | 77 | 在你安装完 Swift 之后,通过 [开始 → 你好,世界](../getting-started/hello-world.md) 来学习创建你的第一个应用。 78 | -------------------------------------------------------------------------------- /docs/install/macos.de.md: -------------------------------------------------------------------------------- 1 | # Installation unter macOS 2 | 3 | Die Mindestvoraussetzung für Vapor unter macOS ist Swift 5.9 (oder aktueller). 4 | 5 | ## Xcode 6 | 7 | Xcode ist Apple`s eigene Entwicklungsumgebung. Du findest die App im [AppStore](https://itunes.apple.com/us/app/xcode/id497799835?mt=12). Mit der Installation von Xcode wird auch gleich Swift mitinstalliert. 8 | 9 | ![Xcode in Mac App Store](../images/xcode-mac-app-store.png) 10 | 11 | Sobald du die App heruntergeladen hast, führe die Installation aus. Starte nach der Installation Xcode um die Installation komplett abzuschließen. Mit dem Termin-Befehl `swift --version` kannst du überprüfen, ob die Installation von Swift erfolgreich verlief und welche Version genau installiert wurde. 12 | 13 | ```sh 14 | swift --version 15 | 16 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 17 | Target: arm64-apple-macosx13.0 18 | ``` 19 | 20 | ## Toolbox 21 | 22 | Neben Swift kannst du auch die Vapor-Toolbox installieren. Die Toolbox ist zwar für Vapor nicht zwingend notwendig, aber beinhaltet Befehle, die dich bei der Arbeit mit Vapor unterstützen. 23 | 24 | Du kannst die Toolbox mittels [Homebrew](https://brew.sh) installieren: 25 | 26 | ```sh 27 | brew install vapor 28 | ``` 29 | 30 | Nach den Installationen kannst du mit der Erstellung deiner ersten Vapor-Anwendung beginnen. Folge dazu den Anweisungen im Abschnitt [Erste Schritte → Hello, world](../getting-started/hello-world.md). 31 | -------------------------------------------------------------------------------- /docs/install/macos.es.md: -------------------------------------------------------------------------------- 1 | # Instalación en macOS 2 | 3 | Para usar Vapor en macOS, necesitarás Swift 5.9 o superior. Swift y todas sus dependencias vienen incluidas con Xcode. 4 | 5 | ## Instalar Xcode 6 | 7 | Instala [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) desde la Mac App Store. 8 | 9 | ![Xcode en la Mac App Store](../images/xcode-mac-app-store.png) 10 | 11 | Una vez que se haya descargado Xcode, debes abrirlo para completar la instalación. Este paso puede tardar un rato. 12 | 13 | Para asegurarse de que la instalación se haya realizado correctamente, abre la Terminal e imprime la versión de Swift. 14 | 15 | ```sh 16 | swift --version 17 | ``` 18 | 19 | Deberías ver la información de la versión de Swift. 20 | 21 | ```sh 22 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 23 | Target: arm64-apple-macosx13.0 24 | ``` 25 | 26 | Vapor 4 requiere Swift 5.9 o superior. 27 | 28 | ## Instalar Toolbox 29 | 30 | Ahora que tienes Swift instalado, vamos a instalar [Vapor Toolbox](https://github.com/vapor/toolbox). Esta aplicación de línea de comando (CLI) no es necesaria para usar Vapor, pero ayuda a crear nuevos proyectos Vapor. 31 | 32 | ### Homebrew 33 | 34 | Toolbox se distribuye a través de Homebrew. Si aún no tienes Homebrew, visita brew.sh para instrucciones de instalación. 35 | 36 | ```sh 37 | brew install vapor 38 | ``` 39 | 40 | Verifica que la instalación se ha realizado correctamente imprimiendo la ayuda. 41 | 42 | ```sh 43 | vapor --help 44 | ``` 45 | 46 | Deberías ver una lista de comandos disponibles. 47 | 48 | ### Makefile 49 | 50 | Si quieres, también puedes compilar la Toolbox desde el código fuente. Consulta las versiones de la Toolbox en GitHub para encontrar la versión más reciente. 51 | 52 | ```sh 53 | git clone https://github.com/vapor/toolbox.git 54 | cd toolbox 55 | git checkout 56 | make install 57 | ``` 58 | 59 | Verifica que la instalación fue exitosa imprimiendo la ayuda. 60 | 61 | ```sh 62 | vapor --help 63 | ``` 64 | 65 | Deberías ver una lista de comandos disponibles. 66 | 67 | ## Siguientes Pasos 68 | 69 | Ahora que tienes instalados Swift y Vapor Toolbox, crea tu primera app en [Comenzando → Hola, mundo](../getting-started/hello-world.md). 70 | -------------------------------------------------------------------------------- /docs/install/macos.it.md: -------------------------------------------------------------------------------- 1 | # Installazione su macOS 2 | 3 | Per usare Vapor su macOS, avrai bisogno di Swift 5.9 o superiore. Swift e tutte le sue dipendenze vengono installati automaticamente quando si installa Xcode. 4 | 5 | ## Installare Xcode 6 | 7 | Puoi installare Xcode dal [Mac App Store](https://apps.apple.com/us/app/xcode/id497799835?mt=12). 8 | 9 | ![Xcode nel Mac App Store](../images/xcode-mac-app-store.png) 10 | 11 | Dopo aver scaricato Xcode, dovrai aprirlo per completare l'installazione. Questo potrebbe richiedere un po' di tempo. 12 | 13 | Controlla che l'installazione sia andata a buon fine aprendo il Terminale e stampando la versione di Swift. 14 | 15 | ```sh 16 | swift --version 17 | ``` 18 | 19 | Dovresti vedere stampate le informazioni della versione di Swift: 20 | 21 | ```sh 22 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 23 | Target: arm64-apple-macosx13.0 24 | ``` 25 | 26 | Vapor 4 richiede Swift 5.9 o superiore. 27 | 28 | ## Installare la Toolbox 29 | 30 | Ora che hai installato Swift, puoi installare la [Vapor Toolbox](https://github.com/vapor/toolbox). Questo strumento da linea di comando non è necessario per usare Vapor, ma aiuta nella creazione dei progetti Vapor. 31 | 32 | ### Homebrew 33 | 34 | La Toolbox è distribuita tramite Homebrew. Se non hai ancora Homebrew, visita brew.sh per le istruzioni di installazione. 35 | 36 | ```sh 37 | brew install vapor 38 | ``` 39 | 40 | Controlla che l'installazione sia andata a buon fine stampando l'aiuto. 41 | 42 | ```sh 43 | vapor --help 44 | ``` 45 | 46 | Dovresti vedere una lista di comandi disponibili. 47 | 48 | ### Makefile 49 | 50 | Se vuoi, puoi compilare la Toolbox dal codice sorgente. Guarda le release della Toolbox su GitHub per trovare l'ultima versione. 51 | 52 | ```sh 53 | git clone https://github.com/vapor/toolbox.git 54 | cd toolbox 55 | git checkout 56 | make install 57 | ``` 58 | 59 | Controlla che l'installazione sia andata a buon fine stampando l'aiuto. 60 | 61 | ```sh 62 | vapor --help 63 | ``` 64 | 65 | Dovresti vedere una lista di comandi disponibili. 66 | 67 | ## Come continuare 68 | 69 | Dopo aver installato Swift e la Vapor Toolbox, puoi iniziare a creare il tuo primo progetto usando [Inizio → Ciao, mondo](../getting-started/hello-world.it.md). 70 | -------------------------------------------------------------------------------- /docs/install/macos.ja.md: -------------------------------------------------------------------------------- 1 | # macOS へのインストール {#install-on-macos} 2 | 3 | Vapor を macOS で使用するには、Swift 5.9 以上が必要です。Swift とそれに関連するすべての依存関係は、Xcode にバンドルされています。 4 | 5 | ## Xcode のインストール {#install-xcode} 6 | 7 | Mac App Store から[Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) をインストールします。 8 | 9 | ![Xcode in Mac App Store](../images/xcode-mac-app-store.png) 10 | 11 | Xcode のダウンロードが完了したら、インストールを完了するために開く必要があります。これには時間がかかる場合があります。 12 | 13 | 14 | インストールが成功したことを確認するために、Terminal を開いて Swift のバージョンを表示してください。 15 | 16 | ```sh 17 | swift --version 18 | ``` 19 | 20 | Swift のバージョン情報が表示されるはずです。 21 | 22 | ```sh 23 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 24 | Target: arm64-apple-macosx13.0 25 | ``` 26 | 27 | Vapor 4 は、Swift 5.9 以上が必要です。 28 | 29 | ## Toolbox のインストール {#install-toolbox} 30 | 31 | Swift をインストールしたので、次に [Vapor Toolbox](https://github.com/vapor/toolbox) をインストールしましょう。この CLI ツールは Vapor を使用するためには必須ではありませんが、新しい Vapor プロジェクトの作成を支援します。 32 | 33 | ### Homebrew 34 | 35 | Toolbox は Homebrew 経由で配布されています。まだ Homebrew をインストールしていない場合は、brew.sh を参照してインストール手順を確認してください。 36 | 37 | ```sh 38 | brew install vapor 39 | ``` 40 | 41 | インストールが成功したかどうかを確認するために、ヘルプを表示してください。 42 | 43 | ```sh 44 | vapor --help 45 | ``` 46 | 47 | 利用可能なコマンドのリストが表示されるはずです。 48 | 49 | ### Makefile 50 | 51 | 必要に応じて、ソースから Toolbox をビルドすることもできます。GitHub の Toolbox のリリースで最新バージョンを見つけてください。 52 | 53 | ```sh 54 | git clone https://github.com/vapor/toolbox.git 55 | cd toolbox 56 | git checkout 57 | make install 58 | ``` 59 | 60 | インストールが成功したかどうかを確認するために、ヘルプを表示してください。 61 | 62 | ```sh 63 | vapor --help 64 | ``` 65 | 66 | 利用可能なコマンドのリストが表示されるはずです。 67 | 68 | ## 次へ {#next} 69 | 70 | Swift と Vapor Toolbox をインストールしたので、 [はじめに → Hello, world](../getting-started/hello-world.md) で初めてのアプリを作成してください。 71 | -------------------------------------------------------------------------------- /docs/install/macos.ko.md: -------------------------------------------------------------------------------- 1 | # macOS에 Vapor 설치하기 2 | 3 | macOS에서 Vapor를 사용하려면 Swift 5.9 이상이 필요합니다. Swift와 그에 필요한 종속성은 Xcode와 함께 번들로 제공됩니다. 4 | 5 | ## Xcode 설치하기 6 | 7 | Mac App Store에서 [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12)를 설치하세요. 8 | 9 | ![Xcode in Mac App Store](../images/xcode-mac-app-store.png) 10 | 11 | Xcode가 다운로드되면 설치를 완료하기 위해 Xcode를 열어야 합니다. 이 작업은 시간이 걸릴 수 있습니다. 12 | 13 | 터미널을 열고 Swift 버전을 출력하여 설치가 성공적으로 이루어졌는지 다시 한 번 확인하세요. 14 | 15 | ```sh 16 | swift --version 17 | ``` 18 | 19 | Swift의 버전 정보가 출력되어야 합니다. 20 | 21 | ```sh 22 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 23 | Target: arm64-apple-macosx13.0 24 | ``` 25 | 26 | Vapor 4는 Swift 5.9 이상을 필요로 합니다. 27 | 28 | ## Toolbox 설치하기 29 | 30 | Swift 설치가 완료된 후, [Vapor Toolbox](https://github.com/vapor/toolbox)를 설치해 봅니다. 이 CLI 도구는 Vapor를 사용하는 데 필요하지는 않지만, 새 프로젝트를 생성하는 등 유용한 유틸리티를 포함하고 있습니다. 31 | 32 | Toolbox는 Homebrew를 통해 배포됩니다. Homebrew를 아직 설치하지 않았다면, brew.sh에서 설치를 합니다. 33 | 34 | ```sh 35 | brew install vapor 36 | ``` 37 | 38 | Toolbox 설치가 성공적으로 이루어졌는지 확인하기 위해 도움말을 출력해보세요. 39 | 40 | ```sh 41 | vapor --help 42 | ``` 43 | 44 | 사용 가능한 명령어 목록이 표시되어야 합니다. 45 | 46 | ## 다음 단계 47 | 48 | 이제 Swift와 Vapor Toolbox를 설치했으므로, [시작하기 → Hello, world](../getting-started/hello-world.ko.md)에서 첫 번째 앱을 생성해보세요. 49 | -------------------------------------------------------------------------------- /docs/install/macos.md: -------------------------------------------------------------------------------- 1 | # Install on macOS 2 | 3 | To use Vapor on macOS, you will need Swift 5.9 or greater. Swift and all of its dependencies come bundled with Xcode. 4 | 5 | ## Install Xcode 6 | 7 | Install [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) from the Mac App Store. 8 | 9 | ![Xcode in Mac App Store](../images/xcode-mac-app-store.png) 10 | 11 | After Xcode has been downloaded, you must open it to complete the installation. This may take a while. 12 | 13 | Double check to ensure that the installation was successful by opening the Terminal and printing the Swift's version. 14 | 15 | ```sh 16 | swift --version 17 | ``` 18 | 19 | You should see Swift's version information printed. 20 | 21 | ```sh 22 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 23 | Target: arm64-apple-macosx13.0 24 | ``` 25 | 26 | Vapor 4 requires Swift 5.9 or greater. 27 | 28 | ## Install Toolbox 29 | 30 | Now that you have Swift installed, let's install the [Vapor Toolbox](https://github.com/vapor/toolbox). This CLI tool is not required to use Vapor, but it helps to create new Vapor projects. 31 | 32 | ### Homebrew 33 | 34 | The Toolbox is distributed via Homebrew. If you do not have Homebrew yet, visit brew.sh for install instructions. 35 | 36 | ```sh 37 | brew install vapor 38 | ``` 39 | 40 | Double check to ensure that the installation was successful by printing help. 41 | 42 | ```sh 43 | vapor --help 44 | ``` 45 | 46 | You should see a list of available commands. 47 | 48 | ### Makefile 49 | 50 | If you want, you can also build the Toolbox from source. View the Toolbox's releases on GitHub to find the latest version. 51 | 52 | ```sh 53 | git clone https://github.com/vapor/toolbox.git 54 | cd toolbox 55 | git checkout 56 | make install 57 | ``` 58 | 59 | Double check the installation was successful by printing help. 60 | 61 | ```sh 62 | vapor --help 63 | ``` 64 | 65 | You should see a list of available commands. 66 | 67 | ## Next 68 | 69 | Now that you have installed Swift and Vapor Toolbox, create your first app in [Getting Started → Hello, world](../getting-started/hello-world.md). 70 | -------------------------------------------------------------------------------- /docs/install/macos.nl.md: -------------------------------------------------------------------------------- 1 | # Installeren op macOS 2 | 3 | Om Vapor te gebruiken op macOS, zal je Swift 5.9 of hoger nodig hebben. Swift en al zijn afhankelijkheden komen gebundeld met Xcode. 4 | 5 | ## Installeer Xcode 6 | 7 | Installeer [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) van de Mac App Store. 8 | 9 | ![Xcode in Mac App Store](../images/xcode-mac-app-store.png) 10 | 11 | Nadat Xcode gedownload is, moet je het openen om de installatie te vervolledigen. Dit kan even duren. 12 | 13 | Controleer nogmaals of de installatie is gelukt door de Terminal te openen en de Swift versie af te drukken. 14 | 15 | ```sh 16 | swift --version 17 | ``` 18 | 19 | Je zou de Swift versie informatie afgedrukt moeten zien. 20 | 21 | ```sh 22 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 23 | Target: arm64-apple-macosx13.0 24 | ``` 25 | 26 | Vapor 4 vereist Swift 5.9 of hoger. 27 | 28 | ## Installeer de Toolbox 29 | 30 | Nu dat Swift geïnstalleerd is, laten we de [Vapor Toolbox](https://github.com/vapor/toolbox) installeren. Deze CLI tool is niet noodzakelijk om Vapor te gebruiken, maar het bevat wel handige hulpprogramma's zoals een nieuwe project creator. 31 | 32 | De Toolbox wordt gedistribueerd via Homebrew. Als je Homebrew nog niet hebt geinstalleerd, bezoek dan brew.sh voor installeer instructies. 33 | 34 | ```sh 35 | brew install vapor 36 | ``` 37 | 38 | Controleer of de installatie is gelukt door het help commando te gebruiken. 39 | 40 | ```sh 41 | vapor --help 42 | ``` 43 | 44 | Je zou een lijst met beschikbare commando's moeten zien. 45 | 46 | ## Next 47 | 48 | Nadat je Swift hebt geïnstalleerd, maak je eerste applicatie in [Aan De Slag → Hallo, wereld](../getting-started/hello-world.md). -------------------------------------------------------------------------------- /docs/install/macos.pl.md: -------------------------------------------------------------------------------- 1 | # Zainstaluj na macOS 2 | 3 | Aby używać Vapor na macOS, potrzebujesz Swift w wersji 5.9 lub wyższej. Swift oraz wszystkie jego zależności są częścią instalacji Xcode. 4 | 5 | ## Zainstaluj Xcode 6 | 7 | Zainstaluj [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) z Mac App Store. 8 | 9 | ![Xcode w Mac App Store](../images/xcode-mac-app-store.png) 10 | 11 | Po tym jak Xcode będzie już pobrany, musi go otworzyć aby skończyć instalacje. To może chwilę zająć. 12 | 13 | Dwa razy sprawdź aby upewnić się że instalacja była sukcesem otwierając Terminal i wyświetlając wersję Swifta. 14 | 15 | ```sh 16 | swift --version 17 | ``` 18 | 19 | Powinna wyświetlić się wersja Swifta. 20 | 21 | ```sh 22 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 23 | Target: arm64-apple-macosx13.0 24 | ``` 25 | 26 | Vapor 4 wymaga wersji Swifta 5.9 lub wyższej. 27 | 28 | ## Zainstaluj Toolbox 29 | 30 | Teraz gdy masz już zainstalowanego Swifta, zainstalujmy [Vapor Toolbox](https://github.com/vapor/toolbox). Jest to narzędzie CLI (z ang. Command Line Interface), które nie jest potrzebne by używać Vapora, natomiast jest wyposażone w przydatne usprawnienia takie jak kreator nowego projektu. 31 | 32 | Toolbox jest wydawany przy pomocy Homebrew. Jeśli jeszcze nie masz Homebrew, to zajrzyj na [brew.sh](https://brew.sh) po instrukcje jak zainstalować. 33 | 34 | ```sh 35 | brew install vapor 36 | ``` 37 | 38 | Sprawdź dwa razy czy instalacja przeszła poprawnie po przez wyświetlenie pomocy. 39 | 40 | ```sh 41 | vapor --help 42 | ``` 43 | 44 | Powinna być widoczna lista dostępnych komend. 45 | 46 | ## Następnie 47 | 48 | Kiedy już udało Ci się zainstalować Swifta, stwórz swoja pierwszą aplikacje w sekcji [Pierwsze kroki → Witaj, świecie](../getting-started/hello-world.md). 49 | -------------------------------------------------------------------------------- /docs/install/macos.zh.md: -------------------------------------------------------------------------------- 1 | # 在 macOS 上安装 2 | 3 | 要在 macOS 上使用 Vapor,你将需要 Swift 5.9 或更高版本。 Swift 及其所有依赖项都与 Xcode 捆绑。 4 | 5 | ## 安装 Xcode 6 | 7 | 从 [Mac App Store](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) 安装 Xcode 或更高版本。 8 | 9 | ![Xcode](https://user-images.githubusercontent.com/1342803/66688324-2396bc80-ec54-11e9-8b96-bd8b29d0ce7c.jpg) 10 | 11 | 下载 Xcode 之后,必须将其打开以完成安装。可能还需要耐心等待一会儿。 12 | 13 | 安装后,打开 Terminal 输入以下命令打印 Swift 的版本,检查版本号以确保安装成功。 14 | 15 | ```sh 16 | swift --version 17 | ``` 18 | 19 | 你应该能够看到 Swift 的版本信息已打印。 20 | 21 | ```sh 22 | swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100) 23 | Target: arm64-apple-macosx13.0 24 | ``` 25 | 26 | Vapor 4 需要 Swift 5.9 或更高版本。 27 | 28 | ## 安装工具箱(Install Toolbox) 29 | 30 | 现在你已经安装了 Swift,让我们安装 [Vapor Toolbox](https://github.com/vapor/toolbox)。 使用 Vapor 不需要此 CLI 工具,但是它包含一些实用的程序,例如新项目创建。 31 | 32 | Toolbox 通过 Homebrew 分发。如果你还没有安装 Homebrew,请访问 brew.sh 查看安装说明。 33 | 34 | ```sh 35 | brew install vapor 36 | ``` 37 | 38 | 通过输出帮助内容以确保安装成功。 39 | 40 | ```sh 41 | vapor --help 42 | ``` 43 | 44 | 你应该可以看到 Vapor 包含的可用命令列表。 45 | 46 | ## 下一步 47 | 48 | 现在你已经安装了 Swift 和 Vapor Toolbox,在 [开始 → 你好,世界](../getting-started/hello-world.md) 中创建你的第一个 Vapor 应用程序。 49 | -------------------------------------------------------------------------------- /docs/javascripts/startSyntaxHighlighting.js: -------------------------------------------------------------------------------- 1 | window.hljs = hljs; 2 | 3 | hljs.highlightAll(); 4 | -------------------------------------------------------------------------------- /docs/leaf/getting-started.zh.md: -------------------------------------------------------------------------------- 1 | # Leaf 2 | 3 | Leaf 是一种强大的模板语言,其语法受 Swift 启发。你可以使用它为前端网站生成动态 HTML 页面或生成内容丰富的电子邮件并通过 API 发送。 4 | 5 | ## Package 6 | 7 | 使用 Leaf 的第一步是将其作为依赖项添加到你项目的 SPM 清单文件中。 8 | 9 | ```swift 10 | // swift-tools-version:5.2 11 | import PackageDescription 12 | 13 | let package = Package( 14 | name: "MyApp", 15 | platforms: [ 16 | .macOS(.v10_15) 17 | ], 18 | dependencies: [ 19 | /// Any other dependencies ... 20 | .package(url: "https://github.com/vapor/leaf.git", from: "4.0.0"), 21 | ], 22 | targets: [ 23 | .target(name: "App", dependencies: [ 24 | .product(name: "Leaf", package: "leaf"), 25 | // Any other dependencies 26 | ]), 27 | // Other targets 28 | ] 29 | ) 30 | ``` 31 | 32 | ## 配置 33 | 34 | 将包添加到项目后,通常在 [`configure.swift`](../getting-started/folder-structure.md#configureswift) 中进行配置,这样 Vapor 就可以使用它了。 35 | 36 | ```swift 37 | import Leaf 38 | 39 | app.views.use(.leaf) 40 | ``` 41 | 42 | 当你调用 `req.view` 时,就是在告诉 Vapor 需要使用 `LeafRenderer` 渲染页面。 43 | 44 | !!! note "注意" 45 | Leaf 有一个用于渲染页面的内部缓存。当 `Application` 的运行环境设置为 `.development` 时,此缓存被禁用,因此对模板的更改会立即生效。在 `.production` 环境和所有的其它环境中,默认启用缓存;应用重启之前,对模板所做的任何更改都不会生效。 46 | 47 | !!! warning "警告" 48 | 从 Xcode 运行项目时为了 Leaf 能够找到模板,你必须为你的 Xcode 工作区设置[自定义工作目录](../getting-started/xcode.md#working-directory)。 49 | 50 | ## 目录结构 51 | 52 | 一旦你配置了 Leaf,你需要确保有一个 `Views` 文件夹来存储 `.leaf` 文件。默认情况下,Leaf 期望文件夹位于相对于项目根目录的 `./Resources/Views` 中。 53 | 54 | 例如,如果你计划提供 Javascript 和 CSS 文件,你可能还希望启用 Vapor 的 [`FileMiddleware`](https://api.vapor.codes/vapor/documentation/vapor/filemiddleware) 服务来提供 `/Public` 文件夹中的文件。 55 | 56 | ``` 57 | VaporApp 58 | ├── Package.swift 59 | ├── Resources 60 | │   ├── Views 61 | │   │   └── hello.leaf 62 | ├── Public 63 | │   ├── images (images resources) 64 | │   ├── styles (css resources) 65 | └── Sources 66 |    └── ... 67 | ``` 68 | 69 | ## 渲染视图 70 | 71 | 现在已经配置了 Leaf,让我们渲染你的第一个模板。在 `Resources/Views` 文件夹中,创建一个新文件,命名为 `hello.leaf`,其内容如下: 72 | 73 | ```leaf 74 | Hello, #(name)! 75 | ``` 76 | 77 | !!! tip "建议" 78 | 如果你正在使用 VSCode 作为代码编辑器,我们推荐安装 [Vapor for VS Code](https://marketplace.visualstudio.com/items?itemName=Vapor.vapor-vscode) 扩展,以启用语法高亮功能。 79 | 80 | 然后,注册一个路由(通常在 `routes.swift` 中或一个控制器中完成注册)来渲染视图。 81 | 82 | ```swift 83 | app.get("hello") { req -> EventLoopFuture in 84 | return req.view.render("hello", ["name": "Leaf"]) 85 | } 86 | 87 | // or 88 | 89 | app.get("hello") { req async throws -> View in 90 | return try await req.view.render("hello", ["name": "Leaf"]) 91 | } 92 | ``` 93 | 94 | 使用 `Request` 上的通用 `view` 属性,而不是直接调用 Leaf。这允许你在测试中切换到不同的渲染器。 95 | 96 | 打开浏览器并访问 `/hello` 路径。你应该看到 `Hello, Leaf!`。恭喜你成功渲染了你的第一个 Leaf 视图! 97 | 98 | -------------------------------------------------------------------------------- /docs/redis/sessions.zh.md: -------------------------------------------------------------------------------- 1 | # Redis & 会话 2 | 3 | Redis 可以作为一个存储提供程序,用于缓存[会话数据](../advanced/sessions.md#session-data),例如用户凭据。 4 | 5 | 如果 [`RedisSessionsDelegate`](https://api.vapor.codes/redis/documentation/redis/redissessionsdelegate) 未提供自定义委托,则将使用默认值。 6 | 7 | ## 默认行为 8 | 9 | ### 创建 SessionID 10 | 11 | 除非在你自己的 [`RedisSessionsDelegate`](#redissessionsdelegate) 中实现 [`makeNewID()`](https://api.vapor.codes/redis/documentation/redis/redissessionsdelegate/makenewid()-3hyne) 方法,否则所有的 ['SessionID`](https://api.vapor.codes/vapor/documentation/vapor/sessionid) 值将通过以下操作创建: 12 | 13 | 1. 生成32字节的随机字符 14 | 1. base64 编码该值 15 | 16 | 例如:`Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=` 17 | 18 | ### 存储会话数据 19 | 20 | `RedisSessionsDelegate` 的默认实现将使用 `Codable` 将 [`SessionData`](https://api.vapor.codes/vapor/documentation/vapor/sessiondata) 存储为一个简单的JSON字符串值。 21 | 22 | 除非在你自己的 `RedisSessionsDelegate` 中实现了 [`makeRedisKey(for:)`](https://api.vapor.codes/redis/documentation/redis/redissessionsdelegate/makerediskey(for:)-5nfge) 方法,`SessionData` 将存储在 Redis 中,其中的键会在 `SessionID` 前加上前缀 `vrs-` (**V**apor **R**edis **S**essions)。 23 | 24 | 例如:`vrs-Hbxozx8rTj+XXGWAzOhh1npZFXaGLpTWpWCaXuo44xQ=` 25 | 26 | ## 注册自定义委托 27 | 28 | 要自定义数据从 Redis 读取和写入的方式,按如下方式注册 `RedisSessionsDelegate` 对象: 29 | 30 | ```swift 31 | import Redis 32 | 33 | struct CustomRedisSessionsDelegate: RedisSessionsDelegate { 34 | // implementation 35 | } 36 | 37 | app.sessions.use(.redis(delegate: CustomRedisSessionsDelegate())) 38 | ``` 39 | 40 | ## RedisSessionsDelegate 41 | 42 | > API 文档:[`RedisSessionsDelegate`](https://api.vapor.codes/redis/documentation/redis/redissessionsdelegate) 43 | 44 | 遵循该协议的对象可以用来改变 `SessionData` 在 Redis 中的存储方式。 45 | 46 | 符合协议的类型只需要实现两个方法:[`redis(_:store:with:)`](https://api.vapor.codes/redis/documentation/redis/redissessionsdelegate/redis(_:store:with:)) 和 [`redis(_:fetchDataFor:)`](https://api.vapor.codes/redis/documentation/redis/redissessionsdelegate/redis(_:fetchdatafor:)) 47 | 48 | 这两者都是必需的,因为你自定义写入会话数据到 Redis 的方式本质上是与如何从 Redis 读取它有内在联系。 49 | 50 | ### RedisSessionsDelegate 哈希示例 51 | 52 | 例如,如果你想将会话数据作为 [Hash 存储在 Redis 中](https://redis.io/topics/data-types-intro#redis-hashes),你将实现如下内容: 53 | 54 | ```swift 55 | func redis( 56 | _ client: Client, 57 | store data: SessionData, 58 | with key: RedisKey 59 | ) -> EventLoopFuture { 60 | // 将每个数据字段存储为单独的哈希字段 61 | return client.hmset(data.snapshot, in: key) 62 | } 63 | func redis( 64 | _ client: Client, 65 | fetchDataFor key: RedisKey 66 | ) -> EventLoopFuture { 67 | return client 68 | .hgetall(from: key) 69 | .map { hash in 70 | // hash 是 [String: RESPValue] 这种类型,因此我们需要尝试解包为字符串 71 | // 并将每个值存储在数据容器中 72 | return hash.reduce(into: SessionData()) { result, next in 73 | guard let value = next.value.string else { return } 74 | result[next.key] = value 75 | } 76 | } 77 | } 78 | ``` 79 | -------------------------------------------------------------------------------- /docs/release-notes.es.md: -------------------------------------------------------------------------------- 1 | # Notas de Versiones de Vapor 2 | 3 | Debido a que es difícil, si no imposible mantener la documentación actualizada constantemente, aquí encontrarás notas de lanzamiento de varios paquetes diferentes vinculados al ecosistema Vapor. 4 | 5 | ## vapor 6 | 7 | ## fluent 8 | 9 | ## fluent-kit 10 | 11 | ## leaf 12 | 13 | ## leaf-kit 14 | 15 | ## fluent-postgres-driver 16 | 17 | ## fluent-mysql-driver 18 | 19 | ## fluent-sqlite-driver 20 | 21 | ## fluent-mongo-driver 22 | 23 | ## postgres-nio 24 | 25 | ## mysql-nio 26 | 27 | ## sqlite-nio 28 | 29 | ## postgres-kit 30 | 31 | ## mysql-kit 32 | 33 | ## sqlite-kit 34 | 35 | ## sql-kit 36 | 37 | ## apns 38 | 39 | ## queues 40 | 41 | ## queues-redis-driver 42 | 43 | ## redis 44 | 45 | ## jwt 46 | 47 | ## jwt-kit 48 | 49 | ## websocket-kit 50 | 51 | ## routing-kit 52 | 53 | ## console-kit 54 | 55 | ## async-kit 56 | 57 | ## multipart-kit 58 | 59 | ## toolbox 60 | 61 | ## core 62 | 63 | ## swift-codecov-action 64 | 65 | ## api-docs 66 | -------------------------------------------------------------------------------- /docs/release-notes.it.md: -------------------------------------------------------------------------------- 1 | # Note sulla Versione di Vapor 2 | 3 | Siccome è difficile, se non impossibile, tenere la documentazione aggiornata costantemente, qui troverai le note sulla versione (release notes) di vari pacchetti differenti legati all'ecosistema Vapor. 4 | 5 | ## vapor 6 | 7 | ## fluent 8 | 9 | ## fluent-kit 10 | 11 | ## leaf 12 | 13 | ## leaf-kit 14 | 15 | ## fluent-postgres-driver 16 | 17 | ## fluent-mysql-driver 18 | 19 | ## fluent-sqlite-driver 20 | 21 | ## fluent-mongo-driver 22 | 23 | ## postgres-nio 24 | 25 | ## mysql-nio 26 | 27 | ## sqlite-nio 28 | 29 | ## postgres-kit 30 | 31 | ## mysql-kit 32 | 33 | ## sqlite-kit 34 | 35 | ## sql-kit 36 | 37 | ## apns 38 | 39 | ## queues 40 | 41 | ## queues-redis-driver 42 | 43 | ## redis 44 | 45 | ## jwt 46 | 47 | ## jwt-kit 48 | 49 | ## websocket-kit 50 | 51 | ## routing-kit 52 | 53 | ## console-kit 54 | 55 | ## async-kit 56 | 57 | ## multipart-kit 58 | 59 | ## toolbox 60 | 61 | ## core 62 | 63 | ## swift-codecov-action 64 | 65 | ## api-docs 66 | -------------------------------------------------------------------------------- /docs/release-notes.ja.md: -------------------------------------------------------------------------------- 1 | # Vapor リリースノート {#vapor-release-notes} 2 | 3 | ドキュメントを常に最新の状態に保つことは困難、あるいは不可能であるため、ここでは Vapor エコシステムに関連する様々なパッケージのリリースノートをご覧いただけます。 4 | 5 | ## vapor 6 | 7 | ## fluent 8 | 9 | ## fluent-kit 10 | 11 | ## leaf 12 | 13 | ## leaf-kit 14 | 15 | ## fluent-postgres-driver 16 | 17 | ## fluent-mysql-driver 18 | 19 | ## fluent-sqlite-driver 20 | 21 | ## fluent-mongo-driver 22 | 23 | ## postgres-nio 24 | 25 | ## mysql-nio 26 | 27 | ## sqlite-nio 28 | 29 | ## postgres-kit 30 | 31 | ## mysql-kit 32 | 33 | ## sqlite-kit 34 | 35 | ## sql-kit 36 | 37 | ## apns 38 | 39 | ## queues 40 | 41 | ## queues-redis-driver 42 | 43 | ## redis 44 | 45 | ## jwt 46 | 47 | ## jwt-kit 48 | 49 | ## websocket-kit 50 | 51 | ## routing-kit 52 | 53 | ## console-kit 54 | 55 | ## async-kit 56 | 57 | ## multipart-kit 58 | 59 | ## toolbox 60 | 61 | ## core 62 | 63 | ## swift-codecov-action 64 | 65 | ## api-docs -------------------------------------------------------------------------------- /docs/release-notes.md: -------------------------------------------------------------------------------- 1 | # Vapor Release Notes 2 | 3 | Because it is hard, if not impossible to keep the documentation up-to-date constantly, here you will find release notes of various different packages linked to the Vapor ecosystem. 4 | 5 | ## vapor 6 | 7 | ## fluent 8 | 9 | ## fluent-kit 10 | 11 | ## leaf 12 | 13 | ## leaf-kit 14 | 15 | ## fluent-postgres-driver 16 | 17 | ## fluent-mysql-driver 18 | 19 | ## fluent-sqlite-driver 20 | 21 | ## fluent-mongo-driver 22 | 23 | ## postgres-nio 24 | 25 | ## mysql-nio 26 | 27 | ## sqlite-nio 28 | 29 | ## postgres-kit 30 | 31 | ## mysql-kit 32 | 33 | ## sqlite-kit 34 | 35 | ## sql-kit 36 | 37 | ## apns 38 | 39 | ## queues 40 | 41 | ## queues-redis-driver 42 | 43 | ## redis 44 | 45 | ## jwt 46 | 47 | ## jwt-kit 48 | 49 | ## websocket-kit 50 | 51 | ## routing-kit 52 | 53 | ## console-kit 54 | 55 | ## async-kit 56 | 57 | ## multipart-kit 58 | 59 | ## toolbox 60 | 61 | ## core 62 | 63 | ## swift-codecov-action 64 | 65 | ## api-docs 66 | -------------------------------------------------------------------------------- /docs/security/crypto.zh.md: -------------------------------------------------------------------------------- 1 | # 加密 2 | 3 | Vapor 中包含 [SwiftCrypto](https://github.com/apple/swift-crypto/) 库,这是苹果 CryptoKit 库的 Linux 兼容端口。SwiftCrypto 还没有公开一些额外的加密 API,比如 [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) 和 [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm)。 4 | 5 | ## SwiftCrypto 6 | 7 | Swift 的 `Crypto` 库实现了苹果的 CryptoKit API。因此,[CryptoKit 文档](https://developer.apple.com/documentation/cryptokit)和 [WWDC 演讲](https://developer.apple.com/videos/play/wwdc2019/709)是学习 API 的绝佳资源。 8 | 9 | 导入 Vapor,即可使用这些 API。 10 | 11 | ```swift 12 | import Vapor 13 | 14 | let digest = SHA256.hash(data: Data("hello".utf8)) 15 | print(digest) 16 | ``` 17 | 18 | CryptoKit 支持下列哈希算法: 19 | 20 | - 哈希:`SHA512`, `SHA384`, `SHA256` 21 | - 消息验证码:`HMAC` 22 | - 密码:`AES`, `ChaChaPoly` 23 | - 公钥密码:`Curve25519`, `P521`, `P384`, `P256` 24 | - 不安全的哈希: `SHA1`, `MD5` 25 | 26 | ## Bcrypt 27 | 28 | Bcrypt 是一种密码哈希算法,它使用一个随机的盐来确保对相同的密码进行多次哈希不会得到相同的摘要。 29 | 30 | Vapor 提供了一个 `Bcrypt` 类型用于哈希和密码比较。 31 | 32 | ```swift 33 | import Vapor 34 | 35 | let digest = try Bcrypt.hash("test") 36 | ``` 37 | 38 | 因为 Bcrypt 使用了盐,所以不能直接比较密码哈希值。明文密码和现有摘要必须同时进行验证。 39 | 40 | ```swift 41 | import Vapor 42 | 43 | let pass = try Bcrypt.verify("test", created: digest) 44 | if pass { 45 | // 密码和摘要匹配。 46 | } else { 47 | // 错误密码。 48 | } 49 | ``` 50 | 51 | 使用 Bcrypt 密码登录可以根据电子邮件或用户名从数据库中获取用户的密码摘要来实现。然后根据提供的明文密码验证已知的摘要。 52 | 53 | ## OTP 54 | 55 | Vapor 支持 HOTP 和 TOTP 一次性密码。OTP 使用 SHA-1、SHA-256 和 SHA-512 哈希函数,可以提供六、七或八位数的输出。OTP 通过生成一次性人类可读密码来提供身份验证。为此,各方首先就对称密钥达成一致,该密钥必须始终保密,以维护生成密码的安全性。 56 | 57 | #### HOTP 58 | 59 | HOTP 是一种基于 HMAC 签名的 OTP。除了对称密钥之外,双方还约定了一个计数器,这是一个为密码提供唯一性的数字。每次尝试后,计数器都会增加。 60 | 61 | ```swift 62 | let key = SymmetricKey(size: .bits128) 63 | let hotp = HOTP(key: key, digest: .sha256, digits: .six) 64 | let code = hotp.generate(counter: 25) 65 | 66 | // 或者使用静态生成函数 67 | HOTP.generate(key: key, digest: .sha256, digits: .six, counter: 25) 68 | ``` 69 | 70 | #### TOTP 71 | 72 | TOTP 是 HOTP 的基于时间的变体。它的工作原理基本相同,但不是简单的计数器,而是使用当前时间来生成唯一性。为了补偿由不同步的时钟、网络延迟、用户延迟和其他混杂因素引入的不可避免的偏差,生成的 TOTP 代码在指定的时间间隔(最常见的是30秒)内保持有效。 73 | 74 | ```swift 75 | let key = SymmetricKey(size: .bits128) 76 | let totp = TOTP(key: key, digest: .sha256, digits: .six, interval: 60) 77 | let code = totp.generate(time: Date()) 78 | 79 | // 或者使用静态生成函数 80 | TOTP.generate(key: key, digest: .sha256, digits: .six, interval: 60, time: Date()) 81 | ``` 82 | 83 | #### Range 84 | 85 | OTP 在提供验证和非同步计数器方面非常有用。两种 OTP 实现都能够生成一个具有容错性的 OTP。 86 | 87 | ```swift 88 | let key = SymmetricKey(size: .bits128) 89 | let hotp = HOTP(key: key, digest: .sha256, digits: .six) 90 | 91 | // 生成一个正确计数器窗口 92 | let codes = hotp.generate(counter: 25, range: 2) 93 | ``` 94 | 95 | 上面的示例允许边距为2,这意味着 HOTP 将计算计数器值为`23...27`,所有这些代码都会被返回。 96 | 97 | !!! warning "警告" 98 | 注意:使用的误差范围越大,攻击者采取行动的时间和自由度就越多,从而降低了算法的安全性。 99 | -------------------------------------------------------------------------------- /docs/security/passwords.es.md: -------------------------------------------------------------------------------- 1 | # Contraseñas 2 | 3 | Vapor incluye una API para el hashing de contraseñas que te ayuda a almacenarlas y verificarlas de forma segura. Esta API es configurable según el entorno y admite hashing asíncrono. 4 | 5 | ## Configuración 6 | 7 | Para configurar el hasher de contraseñas de Application, utiliza `app.passwords`. 8 | 9 | ```swift 10 | import Vapor 11 | 12 | app.passwords.use(...) 13 | ``` 14 | 15 | ### Bcrypt 16 | 17 | Para usar la [API de Bcrypt](crypto.md#bcrypt) de Vapor para el hashing de contraseñas, especifica `.bcrypt`. Esta es la opción predeterminada. 18 | 19 | ```swift 20 | app.passwords.use(.bcrypt) 21 | ``` 22 | 23 | Bcrypt utilizará un coste de 12 a menos que se especifique lo contrario. Puedes configurar esto pasando el parámetro `cost`. 24 | 25 | ```swift 26 | app.passwords.use(.bcrypt(cost: 8)) 27 | ``` 28 | 29 | ### Texto plano 30 | 31 | Vapor incluye un hasher de contraseñas inseguro que almacena y verifica contraseñas como texto plano. Esto no debe usarse en producción, pero puede ser útil para pruebas. 32 | 33 | ```swift 34 | switch app.environment { 35 | case .testing: 36 | app.passwords.use(.plaintext) 37 | default: break 38 | } 39 | ``` 40 | 41 | ## Hashing 42 | 43 | Para hashear contraseñas, utiliza el helper `password` disponible en `Request`. 44 | 45 | ```swift 46 | let digest = try req.password.hash("vapor") 47 | ``` 48 | 49 | Los hashes de contraseñas se pueden verificar con la contraseña en texto plano utilizando el método `verify`. 50 | 51 | ```swift 52 | let bool = try req.password.verify("vapor", created: digest) 53 | ``` 54 | 55 | La misma API está disponible en `Application` para su uso durante el arranque. 56 | 57 | ```swift 58 | let digest = try app.password.hash("vapor") 59 | ``` 60 | 61 | ### Async 62 | Los algoritmos de hashing de contraseñas están diseñados para ser lentos y consumir muchos recursos de CPU. Por esta razón, es posible que desees evitar bloquear el event loop mientras haces el hashing de contraseñas. Vapor proporciona una API asíncrona para hashing de contraseñas que envía el proceso de hashing a un pool de hilos en segundo plano. Para usar la API asíncrona, utiliza la propiedad `async` en un hasher de contraseñas. 63 | 64 | ```swift 65 | req.password.async.hash("vapor").map { digest in 66 | // Utiliza el digest. 67 | } 68 | 69 | // o 70 | 71 | let digest = try await req.password.async.hash("vapor") 72 | ``` 73 | 74 | La verificación de hashes funciona de manera similar: 75 | 76 | ```swift 77 | req.password.async.verify("vapor", created: digest).map { bool in 78 | // Utiliza el resultado. 79 | } 80 | 81 | // o 82 | 83 | let result = try await req.password.async.verify("vapor", created: digest) 84 | ``` 85 | 86 | Calcular hashes en hilos en segundo plano puede liberar los event loops de tu aplicación para manejar más solicitudes entrantes. 87 | -------------------------------------------------------------------------------- /docs/security/passwords.it.md: -------------------------------------------------------------------------------- 1 | # Password 2 | 3 | Vapor include un'API di hashing delle password per aiutarti a conservare e verificare le password in modo sicuro. Questa API è configurabile sulla base di un ambiente e supporta l'hashing asincrono. 4 | 5 | ## Configurazione 6 | 7 | Per configurare la funzione di hash delle password dell'applicazione, usa `app.passwords`. 8 | 9 | ```swift 10 | import Vapor 11 | 12 | app.passwords.use(...) 13 | ``` 14 | 15 | ### Bcrypt 16 | 17 | Per utilizzare [l'API Bcrypt](crypto.it.md#bcrypt) di Vapor per l'hashing delle password, specifica `.bcrypt`. Questa è l'API di default. 18 | 19 | ```swift 20 | app.passwords.use(.bcrypt) 21 | ``` 22 | 23 | Bcrypt utilizzerà un costo di 12 se non diversamente specificato. Puoi configurarlo modificando il parametro `cost`. 24 | 25 | ```swift 26 | app.passwords.use(.bcrypt(cost: 8)) 27 | ``` 28 | 29 | ### Plaintext 30 | 31 | Vapor permette di salvare in modo insicuro le password come testo in chiaro. Normalmente non si dovrebbe fare, ma può essere utile per il testing. 32 | 33 | ```swift 34 | switch app.environment { 35 | case .testing: 36 | app.passwords.use(.plaintext) 37 | default: break 38 | } 39 | ``` 40 | 41 | ## Hashing 42 | 43 | Per ottenere l'hash delle password, usa l'oggetto `password` disponibile in `Request`. 44 | 45 | ```swift 46 | let digest = try req.password.hash("vapor") 47 | ``` 48 | 49 | I digest delle password possono essere verificati paragonandoli alle password in chiaro usando il metodo `verify`. 50 | 51 | ```swift 52 | let bool = try req.password.verify("vapor", created: digest) 53 | ``` 54 | 55 | La stessa API è disponibile in `Application` per usarla all'avvio. 56 | 57 | ```swift 58 | let digest = try app.password.hash("vapor") 59 | ``` 60 | 61 | ### Asincrono 62 | 63 | Gli algoritmi di hashing delle password sono progettati per essere lenti e con un uso intensivo della CPU. Per questo motivo, potresti voler evitare di bloccare il loop di eventi mentre viene calcolato l'hash delle password. Vapor fornisce un'API asincrona di hashing delle password che affida l'hashing a un pool di thread in background. Per usare l'API asincrona, usa la proprietà `async` su una funzione di hash delle password. 64 | 65 | ```swift 66 | req.password.async.hash("vapor").map { digest in 67 | // Gestisci il digest. 68 | } 69 | 70 | // oppure 71 | 72 | let digest = try await req.password.async.hash("vapor") 73 | ``` 74 | 75 | Verificare i digest funziona in modo simile: 76 | 77 | ```swift 78 | req.password.async.verify("vapor", created: digest).map { bool in 79 | // Gestisci il risultato. 80 | } 81 | 82 | // oppure 83 | 84 | let result = try await req.password.async.verify("vapor", created: digest) 85 | ``` 86 | 87 | Calcolare gli hash nei thread in background può liberare i loop di eventi dell'applicazione per gestire più richieste in arrivo. 88 | -------------------------------------------------------------------------------- /docs/security/passwords.ja.md: -------------------------------------------------------------------------------- 1 | # パスワード {#passwords} 2 | 3 | Vaporには、パスワードを安全に保存・検証するためのパスワードハッシュAPIが含まれています。このAPIは環境に基づいて設定可能で、非同期ハッシュ化をサポートしています。 4 | 5 | ## 設定 {#configuration} 6 | 7 | アプリケーションのパスワードハッシャーを設定するには、`app.passwords`を使用します。 8 | 9 | ```swift 10 | import Vapor 11 | 12 | app.passwords.use(...) 13 | ``` 14 | 15 | ### Bcrypt 16 | 17 | パスワードハッシュ化にVaporの[Bcrypt API](crypto.md#bcrypt)を使用するには、`.bcrypt`を指定します。これがデフォルトです。 18 | 19 | ```swift 20 | app.passwords.use(.bcrypt) 21 | ``` 22 | 23 | Bcryptは、特に指定しない限りコスト12を使用します。`cost`パラメータを渡すことで、これを設定できます。 24 | 25 | ```swift 26 | app.passwords.use(.bcrypt(cost: 8)) 27 | ``` 28 | 29 | ### Plaintext 30 | 31 | Vaporには、パスワードを平文として保存・検証する安全でないパスワードハッシャーが含まれています。これは本番環境では使用すべきではありませんが、テストには便利です。 32 | 33 | ```swift 34 | switch app.environment { 35 | case .testing: 36 | app.passwords.use(.plaintext) 37 | default: break 38 | } 39 | ``` 40 | 41 | ## ハッシュ化 {#hashing} 42 | 43 | パスワードをハッシュ化するには、`Request`で利用可能な`password`ヘルパーを使用します。 44 | 45 | ```swift 46 | let digest = try req.password.hash("vapor") 47 | ``` 48 | 49 | パスワードダイジェストは、`verify`メソッドを使用して平文パスワードと照合できます。 50 | 51 | ```swift 52 | let bool = try req.password.verify("vapor", created: digest) 53 | ``` 54 | 55 | 同じAPIは、起動時に使用するために`Application`でも利用可能です。 56 | 57 | ```swift 58 | let digest = try app.password.hash("vapor") 59 | ``` 60 | 61 | ### Async 62 | 63 | パスワードハッシュアルゴリズムは、遅くCPU集約的になるように設計されています。このため、パスワードをハッシュ化する際にイベントループをブロックしないようにしたい場合があります。Vaporは、ハッシュ化をバックグラウンドスレッドプールにディスパッチする非同期パスワードハッシュAPIを提供します。非同期APIを使用するには、パスワードハッシャーの`async`プロパティを使用します。 64 | 65 | ```swift 66 | req.password.async.hash("vapor").map { digest in 67 | // ダイジェストを処理 68 | } 69 | 70 | // または 71 | 72 | let digest = try await req.password.async.hash("vapor") 73 | ``` 74 | 75 | ダイジェストの検証も同様に機能します: 76 | 77 | ```swift 78 | req.password.async.verify("vapor", created: digest).map { bool in 79 | // 結果を処理 80 | } 81 | 82 | // または 83 | 84 | let result = try await req.password.async.verify("vapor", created: digest) 85 | ``` 86 | 87 | バックグラウンドスレッドでハッシュを計算することで、アプリケーションのイベントループを解放し、より多くの受信リクエストを処理できるようになります。 88 | -------------------------------------------------------------------------------- /docs/security/passwords.md: -------------------------------------------------------------------------------- 1 | # Passwords 2 | 3 | Vapor includes a password hashing API to help you store and verify passwords securely. This API is configurable based on environment and supports asynchronous hashing. 4 | 5 | ## Configuration 6 | 7 | To configure the Application's password hasher, use `app.passwords`. 8 | 9 | ```swift 10 | import Vapor 11 | 12 | app.passwords.use(...) 13 | ``` 14 | 15 | ### Bcrypt 16 | 17 | To use Vapor's [Bcrypt API](crypto.md#bcrypt) for password hashing, specify `.bcrypt`. This is the default. 18 | 19 | ```swift 20 | app.passwords.use(.bcrypt) 21 | ``` 22 | 23 | Bcrypt will use a cost of 12 unless otherwise specified. You can configure this by passing the `cost` parameter. 24 | 25 | ```swift 26 | app.passwords.use(.bcrypt(cost: 8)) 27 | ``` 28 | 29 | ### Plaintext 30 | 31 | Vapor includes an insecure password hasher that stores and verifies passwords as plaintext. This should not be used in production but can be useful for testing. 32 | 33 | ```swift 34 | switch app.environment { 35 | case .testing: 36 | app.passwords.use(.plaintext) 37 | default: break 38 | } 39 | ``` 40 | 41 | ## Hashing 42 | 43 | To hash passwords, use the `password` helper available on `Request`. 44 | 45 | ```swift 46 | let digest = try req.password.hash("vapor") 47 | ``` 48 | 49 | Password digests can be verified against the plaintext password using the `verify` method. 50 | 51 | ```swift 52 | let bool = try req.password.verify("vapor", created: digest) 53 | ``` 54 | 55 | The same API is available on `Application` for use during boot. 56 | 57 | ```swift 58 | let digest = try app.password.hash("vapor") 59 | ``` 60 | 61 | ### Async 62 | 63 | Password hashing algorithms are designed to be slow and CPU intensive. Because of this, you may want to avoid blocking the event loop while hashing passwords. Vapor provides an asynchronous password hashing API that dispatches hashing to a background thread pool. To use the asynchronous API, use the `async` property on a password hasher. 64 | 65 | ```swift 66 | req.password.async.hash("vapor").map { digest in 67 | // Handle digest. 68 | } 69 | 70 | // or 71 | 72 | let digest = try await req.password.async.hash("vapor") 73 | ``` 74 | 75 | Verifying digests works similarly: 76 | 77 | ```swift 78 | req.password.async.verify("vapor", created: digest).map { bool in 79 | // Handle result. 80 | } 81 | 82 | // or 83 | 84 | let result = try await req.password.async.verify("vapor", created: digest) 85 | ``` 86 | 87 | Calculating hashes on background threads can free your application's event loops up to handle more incoming requests. 88 | 89 | -------------------------------------------------------------------------------- /docs/security/passwords.nl.md: -------------------------------------------------------------------------------- 1 | # Wachtwoorden 2 | 3 | Vapor bevat een wachtwoord hashing API om u te helpen wachtwoorden veilig op te slaan en te verifiëren. Deze API kan op basis van de omgeving worden geconfigureerd en ondersteunt asynchroon hashen. 4 | 5 | ## Configuratie 6 | 7 | Om de wachtwoord hasher van de Applicatie in te stellen, gebruik `app.passwords`. 8 | 9 | ```swift 10 | import Vapor 11 | 12 | app.passwords.use(...) 13 | ``` 14 | 15 | ### Bcrypt 16 | 17 | Om Vapor's [Bcrypt API](crypto.md#bcrypt) te gebruiken voor het hashen van wachtwoorden, geef `.bcrypt` op. Dit is de standaardinstelling. 18 | 19 | ```swift 20 | app.passwords.use(.bcrypt) 21 | ``` 22 | 23 | Bcrypt zal een waarde van 12 gebruiken, tenzij anders aangegeven. U kunt dit instellen door de `cost` parameter mee te geven. 24 | 25 | ```swift 26 | app.passwords.use(.bcrypt(cost: 8)) 27 | ``` 28 | 29 | ### Plaintext 30 | 31 | Vapor bevat een onveilige wachtwoord hasher die wachtwoorden als plaintext opslaat en verifieert. Dit zou niet in productie gebruikt moeten worden, maar het kan nuttig zijn om te testen. 32 | 33 | ```swift 34 | switch app.environment { 35 | case .testing: 36 | app.passwords.use(.plaintext) 37 | default: break 38 | } 39 | ``` 40 | 41 | ## Hashen 42 | 43 | Om wachtwoorden te hashen, gebruik de `password` helper die beschikbaar is op `Request`. 44 | 45 | ```swift 46 | let digest = try req.password.hash("vapor") 47 | ``` 48 | 49 | Wachtwoord digests kunnen geverifieerd worden met het plaintext wachtwoord via de `verify` methode. 50 | 51 | ```swift 52 | let bool = try req.password.verify("vapor", created: digest) 53 | ``` 54 | 55 | Dezelfde API is beschikbaar op `Application` voor gebruik tijdens het opstarten. 56 | 57 | ```swift 58 | let digest = try app.password.hash("vapor") 59 | ``` 60 | 61 | ### Async 62 | 63 | Hash-algoritmen voor wachtwoorden zijn ontworpen om traag en CPU-intensief te zijn. Daarom wilt u misschien de event loop niet blokkeren tijdens het hashen van wachtwoorden. Vapor biedt een asynchrone wachtwoord hashing API die het hashen naar een achtergrond thread pool stuurt. Om de asynchrone API te gebruiken, gebruik de `async` eigenschap op een wachtwoord hasher. 64 | 65 | ```swift 66 | req.password.async.hash("vapor").map { digest in 67 | // Verwerking afhandelen. 68 | } 69 | 70 | // of 71 | 72 | let digest = try await req.password.async.hash("vapor") 73 | ``` 74 | 75 | Het verifiëren van digests werkt op dezelfde manier: 76 | 77 | ```swift 78 | req.password.async.verify("vapor", created: digest).map { bool in 79 | // Resultaat afhandelen. 80 | } 81 | 82 | // of 83 | 84 | let result = try await req.password.async.verify("vapor", created: digest) 85 | ``` 86 | 87 | Het berekenen van hashes op achtergrond threads kan de event loops van je applicatie vrijmaken om meer inkomende verzoeken af te handelen. 88 | -------------------------------------------------------------------------------- /docs/security/passwords.zh.md: -------------------------------------------------------------------------------- 1 | # 密码 2 | 3 | Vapor 包含一个密码哈希 API,可帮助你安全地存储和验证密码。此 API 可根据环境进行配置,并支持异步哈希。 4 | 5 | ## 配置 6 | 7 | 使用 `app.passwords` 配置应用的密码哈希器 8 | 9 | ```swift 10 | import Vapor 11 | 12 | app.passwords.use(...) 13 | ``` 14 | 15 | ### Bcrypt 16 | 17 | 要使用 Vapor 的 [Bcrypt API](crypto.zh.md#bcrypt) 进行密码哈希,请指定 `.bcrypt`。这也是默认设置。 18 | 19 | ```swift 20 | app.passwords.use(.bcrypt) 21 | ``` 22 | 23 | 除非另有说明,否则 Bcrypt 将使用 cost 为12的默认值。你可以通过传递 `cost` 参数来配置它。 24 | 25 | ```swift 26 | app.passwords.use(.bcrypt(cost: 8)) 27 | ``` 28 | 29 | ### 纯文本 30 | 31 | Vapor 包含一个不安全的密码哈希器,它以明文形式存储和验证密码。这不应该在生产环境中使用,但对测试很有用。 32 | 33 | ```swift 34 | switch app.environment { 35 | case .testing: 36 | app.passwords.use(.plaintext) 37 | default: break 38 | } 39 | ``` 40 | 41 | ## Hashing 42 | 43 | 使用 `Request` 对象上的 `password` 辅助函数对密码进行哈希。 44 | 45 | ```swift 46 | let digest = try req.password.hash("vapor") 47 | ``` 48 | 49 | 可以使用 `verify` 方法针对明文密码验证密码摘要。 50 | 51 | ```swift 52 | let bool = try req.password.verify("vapor", created: digest) 53 | ``` 54 | 55 | 同样的 API 也可以在 `Application` 中使用。 56 | 57 | ```swift 58 | let digest = try app.password.hash("vapor") 59 | ``` 60 | 61 | ### 异步 62 | 63 | 密码哈希算法被设计成速度慢且耗费 CPU 资源。在对密码进行哈希时,你可能希望避免阻塞事件循环。Vapor 提供了一个异步密码哈希 API,它将哈希分派给后台线程池。要使用异步 API,请使用密码哈希器上的 `async` 属性。 64 | 65 | ```swift 66 | req.password.async.hash("vapor").map { digest in 67 | // Handle digest. 68 | } 69 | 70 | // or 71 | 72 | let digest = try await req.password.async.hash("vapor") 73 | ``` 74 | 75 | 验证摘要的工作原理类似: 76 | 77 | ```swift 78 | req.password.async.verify("vapor", created: digest).map { bool in 79 | // Handle result. 80 | } 81 | 82 | // or 83 | 84 | let result = try await req.password.async.verify("vapor", created: digest) 85 | ``` 86 | 87 | 在后台线程上计算哈希值可以释放应用程序的事件循环来处理更多的传入请求。 88 | 89 | 90 | -------------------------------------------------------------------------------- /docs/stylesheets/fonts.css: -------------------------------------------------------------------------------- 1 | /* ==================== */ 2 | /* IMPORT STATIC FONTS */ 3 | /* ==================== */ 4 | 5 | /* ----- Roboto ----- */ 6 | @font-face { 7 | font-family: "Roboto"; 8 | src: url('/assets/fonts/Roboto-Regular.ttf') format("truetype"); 9 | } 10 | 11 | @font-face { 12 | font-family: "Roboto"; 13 | src: url('/assets/fonts/Roboto-Light.ttf') format("truetype"); 14 | font-weight: 300; 15 | font-style: normal; 16 | } 17 | 18 | @font-face { 19 | font-family: "Roboto"; 20 | src: url('/assets/fonts/Roboto-LightItalic.ttf') format("truetype"); 21 | font-weight: 300; 22 | font-style: italic; 23 | } 24 | 25 | @font-face { 26 | font-family: "Roboto"; 27 | src: url('/assets/fonts/Roboto-Italic.ttf') format("truetype"); 28 | font-weight: 400; 29 | font-style: italic; 30 | } 31 | 32 | @font-face { 33 | font-family: "Roboto"; 34 | src: url('/assets/fonts/Roboto-Bold.ttf') format("truetype"); 35 | font-weight: 700; 36 | font-style: normal; 37 | } 38 | 39 | @font-face { 40 | font-family: "Roboto"; 41 | src: url('/assets/fonts/Roboto-BoldItalic.ttf') format("truetype"); 42 | font-weight: 700; 43 | font-style: italic; 44 | } 45 | 46 | /* ----- Roboto Mono ----- */ 47 | @font-face { 48 | font-family: "Roboto Mono"; 49 | src: url('/assets/fonts/RobotoMono-Regular.ttf') format("truetype"); 50 | } 51 | 52 | @font-face { 53 | font-family: "Roboto Mono"; 54 | src: url('/assets/fonts/RobotoMono-Italic.ttf') format("truetype"); 55 | font-weight: 400; 56 | font-style: italic; 57 | } 58 | 59 | @font-face { 60 | font-family: "Roboto Mono"; 61 | src: url('/assets/fonts/RobotoMono-Bold.ttf') format("truetype"); 62 | font-weight: 700; 63 | font-style: normal; 64 | } 65 | 66 | @font-face { 67 | font-family: "Roboto"; 68 | src: url('/assets/fonts/RobotoMono-BoldItalic.ttf') format("truetype"); 69 | font-weight: 700; 70 | font-style: italic; 71 | } 72 | 73 | :root{ 74 | --md-text-font: "Roboto"; 75 | --md-code-font: "Roboto Mono"; 76 | } -------------------------------------------------------------------------------- /docs/version/legacy-docs.es.md: -------------------------------------------------------------------------------- 1 | # Redireccionando... 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/version/legacy-docs.it.md: -------------------------------------------------------------------------------- 1 | # Reindirizzando... 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/version/legacy-docs.ja.md: -------------------------------------------------------------------------------- 1 | # リダイレクト中... 2 | 3 | -------------------------------------------------------------------------------- /docs/version/legacy-docs.md: -------------------------------------------------------------------------------- 1 | # Redirecting... 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/version/legacy-docs.nl.md: -------------------------------------------------------------------------------- 1 | # Omleiden... 2 | 3 | -------------------------------------------------------------------------------- /fixSearchIndex.swift: -------------------------------------------------------------------------------- 1 | #!/usr/bin/swift 2 | 3 | /* 4 | SPDX-License-Identifier: MIT 5 | 6 | Copyright (c) 2023 Vapor 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | import Foundation 28 | 29 | struct SearchIndex: Codable { 30 | let config: SearchIndexConfig 31 | var docs: [SearchIndexDocs] 32 | } 33 | 34 | struct SearchIndexConfig: Codable { 35 | let indexing: String? 36 | let lang: [String] 37 | let minSearchLength: Int? 38 | let prebuildIndex: Bool? 39 | let separator: String? 40 | 41 | enum CodingKeys: String, CodingKey { 42 | case indexing 43 | case lang 44 | case minSearchLength = "min_search_length" 45 | case prebuildIndex = "prebuild_index" 46 | case separator 47 | } 48 | } 49 | 50 | struct SearchIndexDocs: Codable { 51 | let location: String 52 | let text: String 53 | let title: String 54 | } 55 | 56 | let searchIndexPath = "site/search/search_index.json" 57 | 58 | let fileURL = URL(fileURLWithPath: searchIndexPath) 59 | let indexData = try Data(contentsOf: fileURL) 60 | let searchIndex = try JSONDecoder().decode(SearchIndex.self, from: indexData) 61 | var newSearchIndex = searchIndex 62 | var searchIndexDocs = [SearchIndexDocs]() 63 | 64 | let knownLanguages = [ 65 | "en", 66 | "de", 67 | "es", 68 | "fr", 69 | "it", 70 | "ja", 71 | "ko", 72 | "nl", 73 | "pl", 74 | "zh", 75 | ].map { "\($0)/" } 76 | 77 | 78 | for doc in newSearchIndex.docs { 79 | if !knownLanguages.contains(where: { doc.location.starts(with: $0) }) { 80 | searchIndexDocs.append(doc) 81 | } 82 | } 83 | 84 | newSearchIndex.docs = searchIndexDocs 85 | 86 | try JSONEncoder().encode(newSearchIndex).write(to: fileURL) 87 | -------------------------------------------------------------------------------- /googlefc012e5d94cfa05f.html: -------------------------------------------------------------------------------- 1 | google-site-verification: googlefc012e5d94cfa05f.html -------------------------------------------------------------------------------- /markdown-link-check-config.yml: -------------------------------------------------------------------------------- 1 | { 2 | "httpHeaders": { 3 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 4 | }, 5 | "retryCount": 3, 6 | "retryOn": [403, 429, 500, 502, 503, 504], 7 | "ignorePatterns": [ 8 | { "pattern": ".*(localhost|127.0.0.1).*" } 9 | ], 10 | "aliveStatusCodes": [200, 206, 301, 302, 429] 11 | } 12 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-2018 Martin Donath 2 | 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to 5 | # deal in the Software without restriction, including without limitation the 6 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | # sell copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | # IN THE SOFTWARE. 20 | 21 | # Direct dependencies 22 | mkdocs>=1 23 | mkdocs-material>=7.1.0 24 | Pygments>=2.2 25 | pymdown-extensions>=4.11 26 | mkdocs-static-i18n>=0.45 27 | -------------------------------------------------------------------------------- /setUpRedirects.swift: -------------------------------------------------------------------------------- 1 | #!/usr/bin/swift 2 | 3 | /* 4 | SPDX-License-Identifier: MIT 5 | 6 | Copyright (c) 2023 Vapor 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | import Foundation 28 | 29 | let basicDirectories = [ 30 | "async", 31 | "client", 32 | "content", 33 | "environment", 34 | "errors", 35 | "logging", 36 | "routing", 37 | "validation" 38 | ] 39 | 40 | let advancedDirectories = [ 41 | "apns", 42 | "commands", 43 | "files", 44 | "middleware", 45 | "queues", 46 | "server", 47 | "services", 48 | "sessions", 49 | "testing", 50 | "websockets", 51 | ] 52 | 53 | let gettingStartedDirectories = [ 54 | "folder-structure", 55 | "hello-world", 56 | "spm", 57 | "xcode", 58 | ] 59 | 60 | let securityDirectories = [ 61 | "authentication", 62 | "crypto", 63 | "jwt", 64 | "passwords", 65 | ] 66 | 67 | for directory in basicDirectories { 68 | try createRedirect(directory: directory, newDirectory: "basics") 69 | } 70 | 71 | for directory in advancedDirectories { 72 | try createRedirect(directory: directory, newDirectory: "advanced") 73 | } 74 | 75 | for directory in gettingStartedDirectories { 76 | try createRedirect(directory: directory, newDirectory: "getting-started") 77 | } 78 | 79 | for directory in securityDirectories { 80 | try createRedirect(directory: directory, newDirectory: "security") 81 | } 82 | 83 | func createRedirect(directory: String, newDirectory: String) throws { 84 | let redirectString = "" 85 | let fileURL = URL(fileURLWithPath: "site/\(directory)/index.html") 86 | try FileManager.default.createDirectory(atPath: "site/\(directory)", withIntermediateDirectories: true, attributes: nil) 87 | try redirectString.write(to: fileURL, atomically: true, encoding: .utf8) 88 | } 89 | -------------------------------------------------------------------------------- /theme/404.html: -------------------------------------------------------------------------------- 1 | {% extends "main.html" %} 2 | 3 | {% block content %} 4 | 5 |

404 - Page not found

6 |

The page you are looking for may have been removed, changed in name, or it is temporarily unavailable. Please try again later.

7 | Return to the home page 8 | 9 | {% endblock %} -------------------------------------------------------------------------------- /theme/main.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block htmltitle %} 4 | {% if page and page.meta and page.meta.title %} 5 | {{ page.meta.title }} - {{ config.site_name }} 6 | {% elif page and page.title and not page.is_homepage %} 7 | Vapor: {% 8 | if page.parent.title 9 | %} {{ page.parent.title}} → {% 10 | endif 11 | %} {{ page.title }} 12 | {% else %} 13 | {{ config.site_name }} 14 | {% endif %} 15 | {% endblock %} 16 | 17 | {% block styles %} 18 | {{ super() }} 19 | 20 | {% endblock %} 21 | 22 | {% block libs %} 23 | {{ super() }} 24 | 25 | {% endblock %} -------------------------------------------------------------------------------- /theme/scripts/carbon.js: -------------------------------------------------------------------------------- 1 | // data-md-component="toc" 2 | document.addEventListener("DOMContentLoaded", function(event) { 3 | var toc_inner = document.querySelectorAll('.md-sidebar__inner')[1]; 4 | var script = document.createElement("script"); 5 | script.src = '//cdn.carbonads.com/carbon.js?serve=CK7DT2QW&placement=vaporcodes'; 6 | script.type = 'text/javascript'; 7 | script.id = '_carbonads_js'; 8 | 9 | if(typeof toc_inner !== undefined && window.innerWidth > 960) { 10 | toc_inner.appendChild(script); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /theme/styles/carbon.css: -------------------------------------------------------------------------------- 1 | #carbonads * { 2 | margin: initial; 3 | padding: initial; 4 | line-height: initial; 5 | } 6 | 7 | #carbonads { 8 | --carbon-font-size: 12px; 9 | --carbon-padding: 1.5ch; 10 | --carbon-max-char: 20ch; 11 | --carbon-bg-primary: hsl(0, 0%, 98%); 12 | --carbon-bg-secondary: hsl(0, 0%, 92%); 13 | --carbon-text-color: hsl(0, 0%, 20%); 14 | } 15 | 16 | #carbonads { 17 | z-index: 10; 18 | font-size: var(--carbon-font-size); 19 | font-family: var(--carbon-font-family); 20 | } 21 | 22 | #carbonads > span { 23 | display: flex; 24 | flex-direction: column; 25 | min-inline-size: 130px; 26 | max-inline-size: calc( 27 | 130px + calc(var(--carbon-padding) * 2) 28 | ); 29 | margin-inline: 0.6rem; 30 | margin-block-start: 0.6rem; 31 | padding: var(--carbon-padding); 32 | gap: var(--carbon-padding); 33 | background-color: var(--carbon-bg-primary); 34 | box-shadow: 0 0 0 1px var(--carbon-bg-secondary); 35 | } 36 | 37 | #carbonads a { 38 | color: var(--carbon-text-color); 39 | text-decoration: none; 40 | } 41 | 42 | #carbonads a:hover { 43 | color: var(--carbon-text-color); 44 | } 45 | 46 | #carbonads .carbon-wrap { 47 | display: flex; 48 | flex-wrap: wrap; 49 | gap: 1.5ex; 50 | } 51 | 52 | #carbonads .carbon-img { 53 | flex: 0 0 130px; 54 | } 55 | 56 | #carbonads .carbon-img img { 57 | display: block; 58 | } 59 | 60 | #carbonads .carbon-text { 61 | flex-grow: 1; 62 | flex-basis: var(--carbon-max-char); 63 | line-height: 1.4; 64 | text-align: left; 65 | } 66 | 67 | #carbonads .carbon-poweredby { 68 | padding: 6px 8px; 69 | background: var(--carbon-bg-secondary); 70 | color: var(--carbon-text-color); 71 | font-weight: 600; 72 | font-size: 0.6em; 73 | line-height: 1.4; 74 | letter-spacing: 0.2ch; 75 | text-align: center; 76 | text-transform: uppercase; 77 | } --------------------------------------------------------------------------------