From 81788564ce77a6e765bd9a801110f09f51656b31 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 30 Sep 2020 15:44:45 +0200 Subject: [PATCH] Auto-generated example responses in docs - Converted bash generation script to PowerShell - Updated sample data from GettingStarted project - Removed https endpoints, as it breaks starting server during cibuild (no dev-certificate installed) - Fixed warnings for broken links in docs --- Build.ps1 | 13 ++-- appveyor.yml | 20 +++--- docs/api/index.md | 2 +- docs/generate-examples.ps1 | 37 ++++++++++ docs/generate.sh | 43 ----------- docs/request-examples/000-CREATE_Person.sh | 10 --- docs/request-examples/001-CREATE_Article.sh | 18 ----- docs/request-examples/001_GET_Books.ps1 | 1 + docs/request-examples/002-GET_Articles.sh | 1 - .../request-examples/002_GET_Person-by-ID.ps1 | 1 + docs/request-examples/003-GET_Article.sh | 1 - .../003_GET_Books-including-Author.ps1 | 1 + .../004-GET_Articles_With_Authors.sh | 1 - .../004_GET_Books-PublishYear.ps1 | 1 + docs/request-examples/005-PATCH_Article.sh | 11 --- .../005_GET_People-Filter_Partial.ps1 | 1 + docs/request-examples/006-DELETE_Article.sh | 2 - ...Books-sorted-by-PublishYear-descending.ps1 | 1 + docs/request-examples/007-__SEED__.sh | 29 -------- .../007_GET_Books-paginated.ps1 | 1 + .../008-GET_Articles_With_Filter_Eq.sh | 1 - .../009-GET_Articles_With_Filter_Like.sh | 1 - docs/request-examples/010_CREATE_Person.ps1 | 10 +++ .../011_CREATE_Book-with-Author.ps1 | 19 +++++ docs/request-examples/012_PATCH_Book.ps1 | 12 ++++ docs/request-examples/013_DELETE_Book.ps1 | 2 + docs/request-examples/README.md | 12 ++-- docs/request-examples/index.md | 71 ++++++++++--------- docs/request-examples/toc.yml | 0 docs/toc.yml | 10 +-- docs/usage/resource-graph.md | 2 +- docs/usage/resources/attributes.md | 2 +- docs/usage/routing.md | 4 +- src/Examples/GettingStarted/.gitignore | 1 - ...ticlesController.cs => BooksController.cs} | 10 ++- .../GettingStarted/Data/SampleDbContext.cs | 2 +- .../Models/{Article.cs => Book.cs} | 5 +- src/Examples/GettingStarted/Models/Person.cs | 2 +- .../Properties/launchSettings.json | 5 +- src/Examples/GettingStarted/Startup.cs | 35 ++++++--- 40 files changed, 193 insertions(+), 208 deletions(-) create mode 100644 docs/generate-examples.ps1 delete mode 100755 docs/generate.sh delete mode 100755 docs/request-examples/000-CREATE_Person.sh delete mode 100755 docs/request-examples/001-CREATE_Article.sh create mode 100644 docs/request-examples/001_GET_Books.ps1 delete mode 100755 docs/request-examples/002-GET_Articles.sh create mode 100644 docs/request-examples/002_GET_Person-by-ID.ps1 delete mode 100755 docs/request-examples/003-GET_Article.sh create mode 100644 docs/request-examples/003_GET_Books-including-Author.ps1 delete mode 100755 docs/request-examples/004-GET_Articles_With_Authors.sh create mode 100644 docs/request-examples/004_GET_Books-PublishYear.ps1 delete mode 100755 docs/request-examples/005-PATCH_Article.sh create mode 100644 docs/request-examples/005_GET_People-Filter_Partial.ps1 delete mode 100755 docs/request-examples/006-DELETE_Article.sh create mode 100644 docs/request-examples/006_GET_Books-sorted-by-PublishYear-descending.ps1 delete mode 100755 docs/request-examples/007-__SEED__.sh create mode 100644 docs/request-examples/007_GET_Books-paginated.ps1 delete mode 100755 docs/request-examples/008-GET_Articles_With_Filter_Eq.sh delete mode 100755 docs/request-examples/009-GET_Articles_With_Filter_Like.sh create mode 100644 docs/request-examples/010_CREATE_Person.ps1 create mode 100644 docs/request-examples/011_CREATE_Book-with-Author.ps1 create mode 100644 docs/request-examples/012_PATCH_Book.ps1 create mode 100644 docs/request-examples/013_DELETE_Book.ps1 delete mode 100644 docs/request-examples/toc.yml delete mode 100644 src/Examples/GettingStarted/.gitignore rename src/Examples/GettingStarted/Controllers/{ArticlesController.cs => BooksController.cs} (53%) rename src/Examples/GettingStarted/Models/{Article.cs => Book.cs} (70%) diff --git a/Build.ps1 b/Build.ps1 index 96412c0c2e..5ff025d39c 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -1,7 +1,6 @@ # Gets the version suffix from the repo tag # example: v1.0.0-preview1-final => preview1-final -function Get-Version-Suffix-From-Tag -{ +function Get-Version-Suffix-From-Tag { $tag=$env:APPVEYOR_REPO_TAG_NAME $split=$tag -split "-" $suffix=$split[1..2] @@ -32,25 +31,25 @@ CheckLastExitCode Write-Output "APPVEYOR_REPO_TAG: $env:APPVEYOR_REPO_TAG" -If($env:APPVEYOR_REPO_TAG -eq $true) { +if ($env:APPVEYOR_REPO_TAG -eq $true) { $revision = Get-Version-Suffix-From-Tag Write-Output "VERSION-SUFFIX: $revision" - IF ([string]::IsNullOrWhitespace($revision)){ + if ([string]::IsNullOrWhitespace($revision)) { Write-Output "RUNNING dotnet pack .\src\JsonApiDotNetCore -c Release -o .\artifacts" dotnet pack .\src\JsonApiDotNetCore -c Release -o .\artifacts CheckLastExitCode } - Else { + else { Write-Output "RUNNING dotnet pack .\src\JsonApiDotNetCore -c Release -o .\artifacts --version-suffix=$revision" dotnet pack .\src\JsonApiDotNetCore -c Release -o .\artifacts --version-suffix=$revision CheckLastExitCode } } -Else { +else { $packageVersionSuffix="beta1-$revision" Write-Output "VERSION-SUFFIX: $packageVersionSuffix" Write-Output "RUNNING dotnet pack .\src\JsonApiDotNetCore -c Release -o .\artifacts --version-suffix=$packageVersionSuffix" dotnet pack .\src\JsonApiDotNetCore -c Release -o .\artifacts --version-suffix=$packageVersionSuffix CheckLastExitCode -} \ No newline at end of file +} diff --git a/appveyor.yml b/appveyor.yml index 1f1c3b0cce..40238a2b28 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,20 +9,20 @@ environment: # REF: https://github.com/docascode/docfx-seed/blob/master/appveyor.yml before_build: - - ps: | - if(-Not $env:APPVEYOR_PULL_REQUEST_TITLE) - { + - pwsh: | + if (-Not $env:APPVEYOR_PULL_REQUEST_TITLE) { + # https://dotnet.github.io/docfx/tutorial/docfx_getting_started.html git checkout $env:APPVEYOR_REPO_BRANCH -q choco install docfx -y } after_build: - - ps: | - CD ./docs - if(-Not $env:APPVEYOR_PULL_REQUEST_TITLE) - { + - pwsh: | + if (-Not $env:APPVEYOR_PULL_REQUEST_TITLE) { + CD ./docs + & ./generate-examples.ps1 & docfx docfx.json - if ($lastexitcode -ne 0){ + if ($lastexitcode -ne 0) { throw [System.Exception] "docfx build failed with exit code $lastexitcode." } @@ -61,8 +61,8 @@ services: - postgresql96 build_script: -- ps: dotnet --version -- ps: .\Build.ps1 +- pwsh: dotnet --version +- pwsh: .\Build.ps1 test: off diff --git a/docs/api/index.md b/docs/api/index.md index 6d92763517..c8e4a69a3d 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -6,4 +6,4 @@ This section documents the package API and is generated from the XML source comm - [`JsonApiOptions`](JsonApiDotNetCore.Configuration.JsonApiOptions.yml) - [`IResourceGraph`](JsonApiDotNetCore.Configuration.IResourceGraph.yml) -- [`ResourceDefinition`](JsonApiDotNetCore.Resources.ResourceDefinition-1.yml) +- [`JsonApiResourceDefinition`](JsonApiDotNetCore.Resources.JsonApiResourceDefinition-1.yml) diff --git a/docs/generate-examples.ps1 b/docs/generate-examples.ps1 new file mode 100644 index 0000000000..6b6e80d6ac --- /dev/null +++ b/docs/generate-examples.ps1 @@ -0,0 +1,37 @@ +#Requires -Version 7.0 + +# This script generates response documents for ./request-examples + +function Kill-WebServer { + $tcpConnections = Get-NetTCPConnection -LocalPort 14141 -ErrorAction SilentlyContinue + if ($tcpConnections -ne $null) { + Write-Output "Stopping web server" + Get-Process -Id $tcpConnections.OwningProcess | Stop-Process + } +} + +function Start-Webserver { + Write-Output "Starting web server" + Start-Job -ScriptBlock { dotnet run --project ..\src\Examples\GettingStarted\GettingStarted.csproj } | Out-Null +} + +Kill-WebServer +Start-Webserver + +Remove-Item -Force -Path .\request-examples\*.json + +Start-Sleep -Seconds 10 + +$scriptFiles = Get-ChildItem .\request-examples\*.ps1 +foreach ($scriptFile in $scriptFiles) { + $jsonFileName = [System.IO.Path]::GetFileNameWithoutExtension($scriptFile.Name) + "_Response.json" + + Write-Output "Writing file: $jsonFileName" + & $scriptFile.FullName > .\request-examples\$jsonFileName + + if ($LastExitCode -ne 0) { + throw [System.Exception] "Example request from '$($scriptFile.Name)' failed." + } +} + +Kill-WebServer diff --git a/docs/generate.sh b/docs/generate.sh deleted file mode 100755 index 15b368732d..0000000000 --- a/docs/generate.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# generates ./request-examples documents - -function cleanup() { - kill -9 $(lsof -ti tcp:5001) &2>/dev/null -} - -cleanup -dotnet run -p ../src/Examples/GettingStarted/GettingStarted.csproj & -app_pid=$! -echo "Started app with PID $app_pid" - -rm -rf ./request-examples/*.json -rm -rf ./request-examples/*.temp - -{ # try - sleep 10 - - echo "sleep over" - - for path in ./request-examples/*.sh; do - op_name=$(basename "$path" .sh) - file="./request-examples/$op_name-Response.json" - temp_file="./request-examples/$op_name-Response.temp" - - # 1. execute bash script - # 2. redirect stdout to a temp file, this will be the JSON output - # 3. redirect stderr to JSON file, this will be the curl verbose output - # we grab the last line, trim the prefix, add some newlines and the push - # it to the top of the JSON file - bash $path \ - 1> >(jq . > $temp_file) \ - 2> >(grep "HTTP" | tail -n 1 | cut -c 3- | awk '{ printf "%s\n\n",$0 }' > "./request-examples/$op_name-Response.json") - - # append the actual JSON to the file - cat $temp_file >> $file - rm $temp_file - done -} - -# docfx metadata - -cleanup diff --git a/docs/request-examples/000-CREATE_Person.sh b/docs/request-examples/000-CREATE_Person.sh deleted file mode 100755 index 89392b31fb..0000000000 --- a/docs/request-examples/000-CREATE_Person.sh +++ /dev/null @@ -1,10 +0,0 @@ -curl -vs http://localhost:5001/api/people \ - -H "Content-Type: application/vnd.api+json" \ - -d '{ - "data": { - "type": "people", - "attributes": { - "name": "Alice" - } - } - }' \ No newline at end of file diff --git a/docs/request-examples/001-CREATE_Article.sh b/docs/request-examples/001-CREATE_Article.sh deleted file mode 100755 index 236bb5b975..0000000000 --- a/docs/request-examples/001-CREATE_Article.sh +++ /dev/null @@ -1,18 +0,0 @@ -curl -vs http://localhost:5001/api/articles \ - -H "Content-Type: application/vnd.api+json" \ - -d '{ - "data": { - "type": "articles", - "attributes": { - "title": "Moby" - }, - "relationships": { - "author": { - "data": { - "type": "people", - "id": "1" - } - } - } - } - }' \ No newline at end of file diff --git a/docs/request-examples/001_GET_Books.ps1 b/docs/request-examples/001_GET_Books.ps1 new file mode 100644 index 0000000000..559bbfb4d5 --- /dev/null +++ b/docs/request-examples/001_GET_Books.ps1 @@ -0,0 +1 @@ +curl -s -f http://localhost:14141/api/books diff --git a/docs/request-examples/002-GET_Articles.sh b/docs/request-examples/002-GET_Articles.sh deleted file mode 100755 index 46a2c0daa8..0000000000 --- a/docs/request-examples/002-GET_Articles.sh +++ /dev/null @@ -1 +0,0 @@ -curl -vs http://localhost:5001/api/articles diff --git a/docs/request-examples/002_GET_Person-by-ID.ps1 b/docs/request-examples/002_GET_Person-by-ID.ps1 new file mode 100644 index 0000000000..d565c7cf53 --- /dev/null +++ b/docs/request-examples/002_GET_Person-by-ID.ps1 @@ -0,0 +1 @@ +curl -s -f http://localhost:14141/api/people/1 diff --git a/docs/request-examples/003-GET_Article.sh b/docs/request-examples/003-GET_Article.sh deleted file mode 100755 index 2411cbac9f..0000000000 --- a/docs/request-examples/003-GET_Article.sh +++ /dev/null @@ -1 +0,0 @@ -curl -vs http://localhost:5001/api/articles/1 diff --git a/docs/request-examples/003_GET_Books-including-Author.ps1 b/docs/request-examples/003_GET_Books-including-Author.ps1 new file mode 100644 index 0000000000..33f5dcd487 --- /dev/null +++ b/docs/request-examples/003_GET_Books-including-Author.ps1 @@ -0,0 +1 @@ +curl -s -f http://localhost:14141/api/books?include=author diff --git a/docs/request-examples/004-GET_Articles_With_Authors.sh b/docs/request-examples/004-GET_Articles_With_Authors.sh deleted file mode 100755 index dbddb068cb..0000000000 --- a/docs/request-examples/004-GET_Articles_With_Authors.sh +++ /dev/null @@ -1 +0,0 @@ -curl -vs http://localhost:5001/api/articles?include=author diff --git a/docs/request-examples/004_GET_Books-PublishYear.ps1 b/docs/request-examples/004_GET_Books-PublishYear.ps1 new file mode 100644 index 0000000000..bba11d4060 --- /dev/null +++ b/docs/request-examples/004_GET_Books-PublishYear.ps1 @@ -0,0 +1 @@ +curl -s -f http://localhost:14141/api/books?fields=publishYear diff --git a/docs/request-examples/005-PATCH_Article.sh b/docs/request-examples/005-PATCH_Article.sh deleted file mode 100755 index 84d062f920..0000000000 --- a/docs/request-examples/005-PATCH_Article.sh +++ /dev/null @@ -1,11 +0,0 @@ -curl -vs http://localhost:5001/api/people/1 \ - -H "Content-Type: application/vnd.api+json" \ - -X PATCH \ - -d '{ - "data": { - "type": "people", - "attributes": { - "name": "Bob" - } - } - }' \ No newline at end of file diff --git a/docs/request-examples/005_GET_People-Filter_Partial.ps1 b/docs/request-examples/005_GET_People-Filter_Partial.ps1 new file mode 100644 index 0000000000..2e2339f76c --- /dev/null +++ b/docs/request-examples/005_GET_People-Filter_Partial.ps1 @@ -0,0 +1 @@ +curl -s -f "http://localhost:14141/api/people?filter=contains(name,'Shell')" diff --git a/docs/request-examples/006-DELETE_Article.sh b/docs/request-examples/006-DELETE_Article.sh deleted file mode 100755 index 70b237212a..0000000000 --- a/docs/request-examples/006-DELETE_Article.sh +++ /dev/null @@ -1,2 +0,0 @@ -curl -vs http://localhost:5001/api/articles/1 \ - -X DELETE \ No newline at end of file diff --git a/docs/request-examples/006_GET_Books-sorted-by-PublishYear-descending.ps1 b/docs/request-examples/006_GET_Books-sorted-by-PublishYear-descending.ps1 new file mode 100644 index 0000000000..309ad6dcc6 --- /dev/null +++ b/docs/request-examples/006_GET_Books-sorted-by-PublishYear-descending.ps1 @@ -0,0 +1 @@ +curl -s -f http://localhost:14141/api/books?sort=-publishYear diff --git a/docs/request-examples/007-__SEED__.sh b/docs/request-examples/007-__SEED__.sh deleted file mode 100755 index 32ee24b491..0000000000 --- a/docs/request-examples/007-__SEED__.sh +++ /dev/null @@ -1,29 +0,0 @@ -curl -vs http://localhost:5001/api/people \ - -H "Content-Type: application/vnd.api+json" \ - -d '{ - "data": { - "type": "people", - "attributes": { - "name": "Alice" - } - } - }' - -curl -vs http://localhost:5001/api/articles \ - -H "Content-Type: application/vnd.api+json" \ - -d '{ - "data": { - "type": "articles", - "attributes": { - "title": "Moby" - }, - "relationships": { - "author": { - "data": { - "type": "people", - "id": "2" - } - } - } - } - }' \ No newline at end of file diff --git a/docs/request-examples/007_GET_Books-paginated.ps1 b/docs/request-examples/007_GET_Books-paginated.ps1 new file mode 100644 index 0000000000..c088163a52 --- /dev/null +++ b/docs/request-examples/007_GET_Books-paginated.ps1 @@ -0,0 +1 @@ +curl -s -f "http://localhost:14141/api/books?page%5Bsize%5D=1&page%5Bnumber%5D=2" diff --git a/docs/request-examples/008-GET_Articles_With_Filter_Eq.sh b/docs/request-examples/008-GET_Articles_With_Filter_Eq.sh deleted file mode 100755 index a5f3b8de1d..0000000000 --- a/docs/request-examples/008-GET_Articles_With_Filter_Eq.sh +++ /dev/null @@ -1 +0,0 @@ -curl -vs http://localhost:5001/api/articles?filter%5Btitle%5D=Moby diff --git a/docs/request-examples/009-GET_Articles_With_Filter_Like.sh b/docs/request-examples/009-GET_Articles_With_Filter_Like.sh deleted file mode 100755 index 09eae2e692..0000000000 --- a/docs/request-examples/009-GET_Articles_With_Filter_Like.sh +++ /dev/null @@ -1 +0,0 @@ -curl -vs http://localhost:5001/api/people?filter%5Bname%5D=like:Al diff --git a/docs/request-examples/010_CREATE_Person.ps1 b/docs/request-examples/010_CREATE_Person.ps1 new file mode 100644 index 0000000000..1a76f0cad1 --- /dev/null +++ b/docs/request-examples/010_CREATE_Person.ps1 @@ -0,0 +1,10 @@ +curl -s -f http://localhost:14141/api/people ` + -H "Content-Type: application/vnd.api+json" ` + -d '{ + \"data\": { + \"type\": \"people\", + \"attributes\": { + \"name\": \"Alice\" + } + } + }' diff --git a/docs/request-examples/011_CREATE_Book-with-Author.ps1 b/docs/request-examples/011_CREATE_Book-with-Author.ps1 new file mode 100644 index 0000000000..bf839f5a85 --- /dev/null +++ b/docs/request-examples/011_CREATE_Book-with-Author.ps1 @@ -0,0 +1,19 @@ +curl -s -f http://localhost:14141/api/books ` + -H "Content-Type: application/vnd.api+json" ` + -d '{ + \"data\": { + \"type\": \"books\", + \"attributes\": { + \"title\": \"Valperga\", + \"publishYear\": 1823 + }, + \"relationships\": { + \"author\": { + \"data\": { + \"type\": \"people\", + \"id\": \"1\" + } + } + } + } + }' diff --git a/docs/request-examples/012_PATCH_Book.ps1 b/docs/request-examples/012_PATCH_Book.ps1 new file mode 100644 index 0000000000..080115161c --- /dev/null +++ b/docs/request-examples/012_PATCH_Book.ps1 @@ -0,0 +1,12 @@ +curl -s -f http://localhost:14141/api/books/1 ` + -H "Content-Type: application/vnd.api+json" ` + -X PATCH ` + -d '{ + \"data\": { + \"type\": \"books\", + \"id\": "1", + \"attributes\": { + \"publishYear\": 1820 + } + } + }' diff --git a/docs/request-examples/013_DELETE_Book.ps1 b/docs/request-examples/013_DELETE_Book.ps1 new file mode 100644 index 0000000000..d5fdd8e103 --- /dev/null +++ b/docs/request-examples/013_DELETE_Book.ps1 @@ -0,0 +1,2 @@ +curl -s -f http://localhost:14141/api/books/1 ` + -X DELETE diff --git a/docs/request-examples/README.md b/docs/request-examples/README.md index 809dac86c4..4173f27c4f 100644 --- a/docs/request-examples/README.md +++ b/docs/request-examples/README.md @@ -2,18 +2,18 @@ To update these requests: -1. Add a bash (.sh) file prefixed by a number that is used to determine the order the scripts are executed. The bash script should execute a request and output the response. Example: +1. Add a PowerShell (.ps1) script prefixed by a number that is used to determine the order the scripts are executed. The script should execute a request and output the response. Example: ``` -curl -vs http://localhost:5001/api/articles +curl -s http://localhost:14141/api/books ``` 2. Add the example to `index.md`. Example: ``` -## Get Article with Author +### Get with relationship -[!code-sh[GET Request](004-GET_Articles_With_Authors.sh)] -[!code-json[GET Response](004-GET_Articles_With_Authors-Response.json)] +[!code-ps[REQUEST](003_GET_Books-including-Author.ps1)] +[!code-json[RESPONSE](003_GET_Books-including-Author_Response.json)] ``` -3. Run `./generate.sh` +3. Run `./generate-examples.ps1` 4. Verify the results by running `docfx --serve` diff --git a/docs/request-examples/index.md b/docs/request-examples/index.md index 7c41aefe13..58cba05f1c 100644 --- a/docs/request-examples/index.md +++ b/docs/request-examples/index.md @@ -1,63 +1,66 @@ -# Examples +# Example requests These requests have been generated against the "GettingStarted" application and are updated on every deployment. All of these requests have been created using out-of-the-box features. -## Simple CRUD +_Note that cURL requires "[" and "]" in URLs to be escaped._ -### Create +# Reading data -[!code-sh[CREATE](000-CREATE_Person.sh)] -[!code-json[CREATE](000-CREATE_Person-Response.json)] +### Get all -### Create with Relationship +[!code-ps[REQUEST](001_GET_Books.ps1)] +[!code-json[RESPONSE](001_GET_Books_Response.json)] -[!code-sh[CREATE](001-CREATE_Article.sh)] -[!code-json[CREATE](001-CREATE_Article-Response.json)] +### Get by ID +[!code-ps[REQUEST](002_GET_Person-by-ID.ps1)] +[!code-json[RESPONSE](002_GET_Person-by-ID_Response.json)] -### Get All +### Get with relationship -[!code-sh[GET Request](002-GET_Articles.sh)] -[!code-json[GET Response](002-GET_Articles-Response.json)] +[!code-ps[REQUEST](003_GET_Books-including-Author.ps1)] +[!code-json[RESPONSE](003_GET_Books-including-Author_Response.json)] -### Get By Id +### Get sparse fieldset -[!code-sh[GET Request](003-GET_Article.sh)] -[!code-json[GET Response](003-GET_Article-Response.json)] +[!code-ps[REQUEST](004_GET_Books-PublishYear.ps1)] +[!code-json[RESPONSE](004_GET_Books-PublishYear_Response.json)] -### Get with Relationship +### Filter on partial match -[!code-sh[GET Request](004-GET_Articles_With_Authors.sh)] -[!code-json[GET Response](004-GET_Articles_With_Authors-Response.json)] +[!code-ps[REQUEST](005_GET_People-Filter_Partial.ps1)] +[!code-json[RESPONSE](005_GET_People-Filter_Partial_Response.json)] -### Update +### Sorting -[!code-sh[PATCH Request](005-PATCH_Article.sh)] -[!code-json[PATCH Response](005-PATCH_Article-Response.json)] +[!code-ps[REQUEST](006_GET_Books-sorted-by-PublishYear-descending.ps1)] +[!code-json[RESPONSE](006_GET_Books-sorted-by-PublishYear-descending_Response.json)] -### Delete +### Pagination -[!code-sh[DELETE Request](006-DELETE_Article.sh)] -[!code-json[DELETE Response](006-DELETE_Article-Response.json)] +[!code-ps[REQUEST](007_GET_Books-paginated.ps1)] +[!code-json[RESPONSE](007_GET_Books-paginated_Response.json)] -## Filters +# Writing data -_Note that cURL requires URLs to be escaped._ +### Create -### Equality +[!code-ps[REQUEST](010_CREATE_Person.ps1)] +[!code-json[RESPONSE](010_CREATE_Person_Response.json)] -[!code-sh[GET Request](008-GET_Articles_With_Filter_Eq.sh)] -[!code-json[GET Response](008-GET_Articles_With_Filter_Eq-Response.json)] +### Create with relationship -### Like +[!code-ps[REQUEST](011_CREATE_Book-with-Author.ps1)] +[!code-json[RESPONSE](011_CREATE_Book-with-Author_Response.json)] -[!code-sh[GET Request](009-GET_Articles_With_Filter_Like.sh)] -[!code-json[GET Response](009-GET_Articles_With_Filter_Like-Response.json)] +### Update -## Sorting +[!code-ps[REQUEST](012_PATCH_Book.ps1)] +[!code-json[RESPONSE](012_PATCH_Book_Response.json)] -# See Also +### Delete -- Customizing QuerySet +[!code-ps[REQUEST](013_DELETE_Book.ps1)] +[!code-json[RESPONSE](013_DELETE_Book_Response.json)] diff --git a/docs/request-examples/toc.yml b/docs/request-examples/toc.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/toc.yml b/docs/toc.yml index 8ed0880347..e9165998e5 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -8,13 +8,9 @@ href: api/ homepage: api/index.md -# TODO: re-add the examples after I figure out -# how to run ./generate.sh on Appveyor. It may -# be as simple as re-writing it in PS -# -# - name: Request Examples -# href: request-examples/ -# homepage: request-examples/index.md +- name: Examples + href: request-examples/ + homepage: request-examples/index.md - name: Internals href: internals/ diff --git a/docs/usage/resource-graph.md b/docs/usage/resource-graph.md index d6b1f83d8f..e66c6dce17 100644 --- a/docs/usage/resource-graph.md +++ b/docs/usage/resource-graph.md @@ -101,4 +101,4 @@ public class MyModel : Identifiable { /* ... */ } public class MyModel : Identifiable { /* ... */ } ``` -The default naming convention can be changed in [options](./options.md#custom-serializer-settings). +The default naming convention can be changed in [options](~/usage/options.md#custom-serializer-settings). diff --git a/docs/usage/resources/attributes.md b/docs/usage/resources/attributes.md index 7742624b15..549f14483c 100644 --- a/docs/usage/resources/attributes.md +++ b/docs/usage/resources/attributes.md @@ -14,7 +14,7 @@ public class Person : Identifiable There are two ways the public attribute name is determined: -1. Using the configured [naming convention](./options.md#custom-serializer-settings). +1. Using the configured [naming convention](~/usage/options.md#custom-serializer-settings). 2. Individually using the attribute's constructor diff --git a/docs/usage/routing.md b/docs/usage/routing.md index 442bab4d42..2ef38335c8 100644 --- a/docs/usage/routing.md +++ b/docs/usage/routing.md @@ -26,11 +26,11 @@ public class OrderLineController : JsonApiController { /* .... */ } GET /orderLines HTTP/1.1 ``` -The public name of the resource ([which can be customized](./resource-graph.md#public-resource-name)) is used for the route, instead of the controller name. +The public name of the resource ([which can be customized](~/usage/resource-graph.md#public-resource-name)) is used for the route, instead of the controller name. ### Non-json:api controllers -If a controller does not inherit from `JsonApiController`, the [configured naming convention](./options.md#custom-serializer-settings) is applied to the name of the controller. +If a controller does not inherit from `JsonApiController`, the [configured naming convention](~/usage/options.md#custom-serializer-settings) is applied to the name of the controller. ```c# public class OrderLineController : ControllerBase { /* .... */ } ``` diff --git a/src/Examples/GettingStarted/.gitignore b/src/Examples/GettingStarted/.gitignore deleted file mode 100644 index 98e6ef67fa..0000000000 --- a/src/Examples/GettingStarted/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.db diff --git a/src/Examples/GettingStarted/Controllers/ArticlesController.cs b/src/Examples/GettingStarted/Controllers/BooksController.cs similarity index 53% rename from src/Examples/GettingStarted/Controllers/ArticlesController.cs rename to src/Examples/GettingStarted/Controllers/BooksController.cs index ad73a9e9bd..17e1c1417d 100644 --- a/src/Examples/GettingStarted/Controllers/ArticlesController.cs +++ b/src/Examples/GettingStarted/Controllers/BooksController.cs @@ -6,13 +6,11 @@ namespace GettingStarted.Controllers { - public sealed class ArticlesController : JsonApiController
+ public sealed class BooksController : JsonApiController { - public ArticlesController( - IJsonApiOptions options, - ILoggerFactory loggerFactory, - IResourceService
resourceService) + public BooksController(IJsonApiOptions options, ILoggerFactory loggerFactory, IResourceService resourceService) : base(options, loggerFactory, resourceService) - { } + { + } } } diff --git a/src/Examples/GettingStarted/Data/SampleDbContext.cs b/src/Examples/GettingStarted/Data/SampleDbContext.cs index 80397254d8..b58223da50 100644 --- a/src/Examples/GettingStarted/Data/SampleDbContext.cs +++ b/src/Examples/GettingStarted/Data/SampleDbContext.cs @@ -5,7 +5,7 @@ namespace GettingStarted.Data { public class SampleDbContext : DbContext { - public DbSet
Articles { get; set; } + public DbSet Books { get; set; } public SampleDbContext(DbContextOptions options) : base(options) diff --git a/src/Examples/GettingStarted/Models/Article.cs b/src/Examples/GettingStarted/Models/Book.cs similarity index 70% rename from src/Examples/GettingStarted/Models/Article.cs rename to src/Examples/GettingStarted/Models/Book.cs index eb7d0d8093..9e4ae01b50 100644 --- a/src/Examples/GettingStarted/Models/Article.cs +++ b/src/Examples/GettingStarted/Models/Book.cs @@ -3,11 +3,14 @@ namespace GettingStarted.Models { - public sealed class Article : Identifiable + public sealed class Book : Identifiable { [Attr] public string Title { get; set; } + [Attr] + public int PublishYear { get; set; } + [HasOne] public Person Author { get; set; } } diff --git a/src/Examples/GettingStarted/Models/Person.cs b/src/Examples/GettingStarted/Models/Person.cs index 161ed14e58..35551bb311 100644 --- a/src/Examples/GettingStarted/Models/Person.cs +++ b/src/Examples/GettingStarted/Models/Person.cs @@ -10,6 +10,6 @@ public sealed class Person : Identifiable public string Name { get; set; } [HasMany] - public ICollection
Articles { get; set; } + public ICollection Books { get; set; } } } diff --git a/src/Examples/GettingStarted/Properties/launchSettings.json b/src/Examples/GettingStarted/Properties/launchSettings.json index 7083903219..9ea0e9d79b 100644 --- a/src/Examples/GettingStarted/Properties/launchSettings.json +++ b/src/Examples/GettingStarted/Properties/launchSettings.json @@ -4,8 +4,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:14141", - "sslPort": 44344 + "applicationUrl": "http://localhost:14141" } }, "profiles": { @@ -21,7 +20,7 @@ "commandName": "Project", "launchBrowser": false, "launchUrl": "api/people", - "applicationUrl": "https://localhost:44344;http://localhost:14141", + "applicationUrl": "http://localhost:14141", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Examples/GettingStarted/Startup.cs b/src/Examples/GettingStarted/Startup.cs index 5d9c096457..b97618f823 100644 --- a/src/Examples/GettingStarted/Startup.cs +++ b/src/Examples/GettingStarted/Startup.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json; namespace GettingStarted { @@ -16,7 +17,13 @@ public void ConfigureServices(IServiceCollection services) options => options.UseSqlite("Data Source=sample.db")); services.AddJsonApi( - options => options.Namespace = "api"); + options => + { + options.Namespace = "api"; + options.UseRelativeLinks = true; + options.IncludeTotalResourceCount = true; + options.SerializerSettings.Formatting = Formatting.Indented; + }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -32,20 +39,32 @@ public void Configure(IApplicationBuilder app, SampleDbContext context) } private static void CreateSampleData(SampleDbContext context) - { - context.Articles.AddRange(new Article + { + // Note: The generate-examples.ps1 script (to create example requests in documentation) depends on these. + + context.Books.AddRange(new Book + { + Title = "Frankenstein", + PublishYear = 1818, + Author = new Person + { + Name = "Mary Shelley" + } + }, new Book { - Title = "What's new in JsonApiDotNetCore", + Title = "Robinson Crusoe", + PublishYear = 1719, Author = new Person { - Name = "John Doe" + Name = "Daniel Defoe" } - }, new Article + }, new Book { - Title = ".NET Core Best Practices", + Title = "Gulliver's Travels", + PublishYear = 1726, Author = new Person { - Name = "Microsoft" + Name = "Jonathan Swift" } });