Pular para o conteúdo principal

Migration Guide

OpenAPI 3.1 Support (Added in 6.1)​

Non-Breaking Addition

Version 6.1 adds full support for OpenAPI 3.1 with JSON Schema 2020-12 compatibility. All existing code continues to work without changes.

What's New in OpenAPI 3.1​

  • Automatic Version Detection: The library now automatically detects and handles OpenAPI 3.1 schemas
  • Type Array Nullable: Support for JSON Schema union types like ["string", "null"]
  • Webhooks: Test incoming HTTP requests your API will receive
  • Modern JSON Schema Keywords: const, if/then/else, prefixItems for tuples
  • Enhanced $ref: References can have sibling keywords

Migration from OpenAPI 3.0 to 3.1​

No Code Changes Required

The library automatically detects the version - your existing code works with both 3.0 and 3.1 schemas!

Example: Automatic version detection
// This works for both 3.0 and 3.1
$schema = Schema::fromFile('/path/to/openapi.json');

// Check which version you're using
echo $schema->getSpecificationVersion(); // "3.0" or "3.1"

Updating Your OpenAPI Schemas​

If you want to upgrade your OpenAPI schemas from 3.0 to 3.1:

1. Update the version number:

Update OpenAPI version
{
"openapi": "3.1.0"
}

2. Replace nullable with type arrays (optional but recommended):

Before (OpenAPI 3.0):

{
"type": "string",
"nullable": true
}

After (OpenAPI 3.1):

{
"type": [
"string",
"null"
]
}

3. Use webhooks for incoming requests (new feature):

Example: Webhook definition
{
"openapi": "3.1.0",
"webhooks": {
"newUser": {
"post": {
"requestBody": {},
"responses": {}
}
}
}
}

For detailed information on OpenAPI 3.1 features, see OpenAPI 3.1 Features Guide.

Backward Compatibility​

100% Backward Compatible
  • ✅ All OpenAPI 3.0 and Swagger 2.0 schemas work without changes
  • ✅ All existing test code continues to work
  • ✅ No breaking changes
  • ✅ Mixed 3.0 and 3.1 schemas can be used in the same project

Migrating from Schema::getInstance() (Deprecated in 6.0)​

Deprecated

The Schema::getInstance() method has been deprecated in version 6.0 and will be removed in version 7.0.

Why the Change?​

Reason for Deprecation

The method name getInstance() suggests a singleton pattern, but it actually creates new instances each time (factory pattern). This is confusing for developers.

New Factory Methods​

Three new, clearer factory methods have been added:

Old Way (Deprecated):

// From JSON string
$schema = Schema::getInstance(file_get_contents('/path/to/spec.json'));

// From array
$schema = Schema::getInstance($arrayData);

New Way (Recommended):

// From file (recommended - simplest)
$schema = Schema::fromFile('/path/to/spec.json');

// From JSON string
$jsonString = file_get_contents('/path/to/spec.json');
$schema = Schema::fromJson($jsonString);

// From array
$schema = Schema::fromArray($arrayData);

// With null values allowed (Swagger 2.0 only)
$schema = Schema::fromFile('/path/to/spec.json', allowNullValues: true);
$schema = Schema::fromJson($jsonString, allowNullValues: true);
$schema = Schema::fromArray($arrayData, allowNullValues: true);

Benefits​

Why Use New Methods
  1. Clearer intent: Method name matches what it does (factory, not singleton)
  2. Better error messages: Each method validates its specific input type
  3. More convenient: fromFile() handles file reading for you
  4. Consistent naming: Follows common factory method patterns

Migrating from assertRequest() (Deprecated in 6.0)​

Deprecated

The assertRequest() method has been renamed to sendRequest() for clarity.

Why the Change?​

Reason for Deprecation

The method name assertRequest() is misleading because:

  • It returns a value (assertions typically don't return)
  • The actual validation happens inside via exceptions
  • Developers expect assertion methods to be void

Migration​

Old Way (Deprecated):

$response = $this->assertRequest($request);

New Way:

$response = $this->sendRequest($request);

That's it! The functionality is identical, just the name is clearer.


Migrating to expect* Methods (Version 6.0)​

Renamed for Clarity

The assertion-style methods (assertStatus(), assertResponseCode(), assertBodyContains(), etc.) have been renamed to expectation-style methods in version 6.0 for better semantic clarity.

Why the Change?​

The new "expect" terminology is more semantically accurate:

  • These methods set up expectations that are validated later when sendRequest() is called
  • They don't immediately assert - they register expectations to validate after the response
  • "Expect" clearly indicates you're defining what you expect, not asserting what already happened
  • Common pattern in testing frameworks (PHPUnit prophecy, Mockery, etc.)

Migration​

Old Way:

$request = new ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1')
->assertResponseCode(200) // or assertStatus(200)
->assertBodyContains('Spike')
->assertHeaderContains('Content-Type', 'json');

New Way:

$request = new ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1')
->expectStatus(200)
->expectBodyContains('Spike')
->expectHeaderContains('Content-Type', 'json');

Method Mapping​

Old MethodNew Method
assertResponseCode()expectStatus()
assertStatus()expectStatus()
assertBodyContains()expectBodyContains()
assertHeaderContains()expectHeaderContains()
assertJsonContains()expectJsonContains()
assertJsonPath()expectJsonPath()

Migrating from makeRequest() (Deprecated in 6.0)​

Deprecated

The makeRequest() method with 6 parameters has been deprecated in version 6.0 and will be removed in version 7.0.

Why the Change?​

Old makeRequest() Issues:

  • Required passing 6 parameters (even empty ones)
  • Parameters in specific order
  • Not easily extensible
  • Less readable code

New ApiRequester Benefits:

  • More readable and self-documenting
  • Only specify parameters you need
  • Easy to extend with new features
  • Better IDE autocomplete support

Migration Examples​

Example 1: Simple GET Request​

Old Way (Deprecated):

protected function testGetPet()
{
$this->makeRequest(
'GET',
'/pet/1',
200,
null,
null,
[]
);
}

New Way:

public function testGetPet()
{
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1');

$this->sendRequest($request);
}

Example 2: POST with Body​

Old Way (Deprecated):

protected function testCreatePet()
{
$this->makeRequest(
'POST',
'/pet',
201,
null,
['name' => 'Fluffy', 'status' => 'available'],
[]
);
}

New Way:

public function testCreatePet()
{
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('POST')
->withPath('/pet')
->withRequestBody(['name' => 'Fluffy', 'status' => 'available'])
->expectStatus(201);

$this->sendRequest($request);
}

Example 3: GET with Query Parameters​

Old Way (Deprecated):

protected function testFindPets()
{
$this->makeRequest(
'GET',
'/pet/findByStatus',
200,
['status' => 'available'],
null,
[]
);
}

New Way:

public function testFindPets()
{
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/findByStatus')
->withQuery(['status' => 'available']);

$this->sendRequest($request);
}

Example 4: Request with Headers​

Old Way (Deprecated):

protected function testAuthenticatedRequest()
{
$this->makeRequest(
'GET',
'/pet/1',
200,
null,
null,
['Authorization' => 'Bearer token123']
);
}

New Way:

public function testAuthenticatedRequest()
{
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1')
->withRequestHeader(['Authorization' => 'Bearer token123']);

$this->sendRequest($request);
}

Example 5: Complex Request with All Parameters​

Old Way (Deprecated):

protected function testComplexRequest()
{
$response = $this->makeRequest(
'POST',
'/pet/1',
200,
['detailed' => 'true'],
['name' => 'Updated Name'],
['Authorization' => 'Bearer token123']
);
}

New Way:

public function testComplexRequest()
{
$request = new \ByJG\ApiTools\ApiRequester();
$response = $request
->withMethod('POST')
->withPath('/pet/1')
->withQuery(['detailed' => 'true'])
->withRequestBody(['name' => 'Updated Name'])
->withRequestHeader(['Authorization' => 'Bearer token123'])
->expectStatus(200);

$response = $this->sendRequest($request);
}

Additional Benefits of the New Approach​

1. Better Assertions​

Multiple Expectations

You can add multiple assertions to your request:

Example: Multiple expectations
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1')
->expectStatus(200)
->expectHeaderContains('Content-Type', 'application/json')
->expectBodyContains('Fluffy');

$this->sendRequest($request);

2. Reusable Request Builders​

Helper Methods

You can create helper methods that return configured requesters:

Example: Reusable authenticated request
protected function createAuthenticatedRequest(string $method, string $path): \ByJG\ApiTools\ApiRequester
{
$request = new \ByJG\ApiTools\ApiRequester();
return $request
->withMethod($method)
->withPath($path)
->withRequestHeader(['Authorization' => 'Bearer ' . $this->getToken()]);
}

public function testWithHelper()
{
$request = $this->createAuthenticatedRequest('GET', '/pet/1');
$this->sendRequest($request);
}

3. Response Inspection​

Response Analysis

Both methods return the response, allowing you to inspect it further:

Example: Inspecting response data
$request = new \ByJG\ApiTools\ApiRequester();
$request
->withMethod('GET')
->withPath('/pet/1');

$response = $this->sendRequest($request);

// Inspect the response
$body = json_decode((string)$response->getBody(), true);
$this->assertEquals('Fluffy', $body['name']);

Timeline​

Deprecation Timeline
  • Version 6.0:
    • Schema::getInstance() deprecated (use fromJson(), fromArray(), or fromFile())
    • assertRequest() deprecated (use sendRequest())
    • makeRequest() deprecated (use ApiRequester fluent interface)
  • Version 7.0: All deprecated methods will be removed

Need Help?​

Getting Support

If you encounter issues during migration:

  1. Check the Troubleshooting Guide
  2. Review the API Reference
  3. Open an issue on GitHub