On a current project I am working on, we are implementing quite a few web APIs which is consumed by different frontend applications. The project is still in the beginning, but we thought it would be cool to ensure the API response JSON schema does not change accidentally by a developer. Therefore, I started to look into different solutions and just found the simplest one.
The simplest solution is to use Test-Json -SchemaFile
function from the PowerShell – to able to use this function you have to install PowerShell 7.3+. If you just want to test one API and don’t need a framework to run it by pipelines or git hooks, you can stop here 🤚. In the following section, I’ll show you how you can organize the scripts and run all tests at once.
Folders, configs, scripts and structure…
So I have an approach to do the JSON schema test for one API but I would like to have a system which is able to run all test scripts and show the failed tests. Therefore, I came up with the following file structure inside the git repository.
└─ 📂 tests | |
└─ 📂 api-tests | |
└─ 📂 <area> | |
├─ 📂 <api1> | |
│ ├─ 📄 response-schema.json | |
│ └─ 📄 test.ps1 | |
├─ 📂 <api2> | |
│ ├─ 📄 response-schema.json | |
│ └─ 📄 test.ps1 | |
├─ 📂 <api3> | |
│ ├─ 📄 response-schema.json | |
│ └─ 📄 test.ps1 | |
└─ ⚙ config.json |
So let’s check these files one-by-one.
1. test.ps1
$config = Get-Content ../config.json | ConvertFrom-Json | |
$apiRoute = $config.SitecoreHost + '/api/<area>/<api1>' | |
$result = Invoke-WebRequest $apiRoute | |
Test-Json -Json $result -SchemaFile .\response-schema.json |
2. config.json
{ | |
"Host": "localhost:3000" | |
} |
3. response-schema.json
I used this tool generate JSON schema for the API:
{ | |
"$schema": "http://json-schema.org/draft-06/schema#", | |
"$ref": "#/definitions/Welcome1", | |
"definitions": { | |
"Welcome1": { | |
"type": "object", | |
"additionalProperties": false, | |
"properties": { | |
"SomeObject": { | |
"$ref": "#/definitions/SomeObject" | |
} | |
}, | |
"required": [ | |
"SomeObject" | |
], | |
"title": "Welcome1" | |
}, | |
"SomeObject": { | |
"type": "object", | |
"additionalProperties": false, | |
"properties": { | |
"SomeStringProperty": { | |
"type": "string" | |
}, | |
"SomeNumberProperty": { | |
"type": "integer" | |
}, | |
"SomeArrayProperty": { | |
"type": "array", | |
"items": { | |
"type": "string" | |
} | |
} | |
}, | |
"required": [ | |
"SomeArrayProperty", | |
"SomeNumberProperty", | |
"SomeStringProperty" | |
], | |
"title": "SomeObject" | |
} | |
} | |
} |
Git hook
As mentioned in the intro, I built this structure to able run all tests at once by a git hook. So this will prevent to commit broken web API schemas which would potentially break the consumer applications. So, here is the script and git hook.
try { | |
Get-ChildItem .\tests\api-tests\**.ps1 -Recurse | ForEach-Object { | |
Set-Location -Path $_.Directory | |
Write-Host "Running test: " .\ $_.Directory.Name \ $_.Name " -> " -NoNewline -Separator '' | |
(& $_.FullName) ? "Passed" : "Failed" | |
} | |
} | |
catch { | |
Write-Host "Failed" | |
throw; | |
} | |
finally { | |
Set-Location -Path $PSScriptRoot | |
} |
#!/bin/sh | |
pwsh.exe -ExecutionPolicy RemoteSigned -File '.githooks\pre-commit.ps1' |
If you would like to version control the two files above you should put it in a separated .githooks
folder instead of .git/hooks
. Then to change the hooks path configuration you need to run the following script on each machine:
$ git config core.hooksPath .\.githooks\
I uploaded the full solution to GitHub!