Web API JSON result schema testing with PowerShell and Git Hook

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
view raw test.ps1 hosted with ❤ by GitHub

2. config.json

{
"Host": "localhost:3000"
}
view raw config.json hosted with ❤ by GitHub

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
}
view raw pre-commit.ps1 hosted with ❤ by GitHub
#!/bin/sh
pwsh.exe -ExecutionPolicy RemoteSigned -File '.githooks\pre-commit.ps1'
view raw pre-commit hosted with ❤ by GitHub

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!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s