From 8225230f76883eac505b72be0306aeecaae51f7b Mon Sep 17 00:00:00 2001 From: Kaushal Vora Date: Wed, 23 Apr 2025 23:14:52 +0530 Subject: [PATCH 1/3] Added virtual service documentation --- documentation/stateful_service.md | 316 ++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 documentation/stateful_service.md diff --git a/documentation/stateful_service.md b/documentation/stateful_service.md new file mode 100644 index 00000000..8b0a8c57 --- /dev/null +++ b/documentation/stateful_service.md @@ -0,0 +1,316 @@ +--- +layout: default +title: Stateful Service +parent: Documentation +nav_order: 36 +--- + +# Stateful Service + + + + +- [Stateful Service](#stateful-service) + - [Pre-requisites](#pre-requisites) + - [Example Usage](#example-usage) + - [Command Line Options](#command-line-options) + - [Working with State](#working-with-state) + - [Default Behavior](#default-behavior) + - [Pre-loading State](#pre-loading-state) + - [Common Use Cases](#common-use-cases) + - [Local Development](#local-development) + - [Integration Testing](#integration-testing) + - [API Design Validation](#api-design-validation) + - [Troubleshooting](#troubleshooting) + - [Common Issues](#common-issues) + - [See Also](#see-also) + + + +While Specmatic's service virtualization provides stateless API mocking capabilities, modern applications often require more sophisticated testing scenarios. The virtual service feature was introduced to address this need, providing stateful behavior that mirrors real-world API interactions. + +**Key differences from service virtualization:** +- Maintains state across requests +- Enables testing of complex workflows +- Supports scenarios requiring data persistence +- Allows validation of state-dependent business logic + +**This makes virtual-service particularly valuable for:** +- Testing multi-step API workflows +- Validating state transitions +- Simulating real-world API behaviors +- Development without external service dependencies + +**Note:** RESTful api specification is mandatory for using Specmatic's stateful service feature. + +## Pre-requisites + +- Create a directory named `specmatic` in your home directory. +- Make sure you have installed Specmatic. Explore the [Getting Started](/documentation/service_virtualization_tutorial.html) page for all options for installing Specmatic. + +## Example Usage + +- Create a file named `employees.yaml` in the `specmatic` directory with the following contents. + +```yaml +openapi: 3.0.0 +info: + title: Employees + version: '1.0' +paths: + /employees: + get: + summary: Get all employees + responses: + '200': + description: List of employees + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/EmployeeWithId' + post: + summary: Create a new employee + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Employee' + responses: + '201': + description: Employee created + content: + application/json: + schema: + $ref: '#/components/schemas/EmployeeWithId' + /employees/{id}: + get: + summary: Get a single employee by ID + parameters: + - name: id + in: path + required: true + schema: + type: integer + responses: + '200': + description: Employee details + content: + application/json: + schema: + $ref: '#/components/schemas/EmployeeWithId' + '404': + description: Employee not found + put: + summary: Update an existing employee + parameters: + - name: id + in: path + required: true + schema: + type: integer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Employee' + responses: + '200': + description: Employee updated + content: + application/json: + schema: + $ref: '#/components/schemas/EmployeeWithId' + '404': + description: Employee not found + delete: + summary: Delete an employee + parameters: + - name: id + in: path + required: true + schema: + type: integer + responses: + '204': + description: Employee deleted + '404': + description: Employee not found + +components: + schemas: + Employee: + type: object + required: + - name + - department + - designation + properties: + name: + type: string + department: + type: string + designation: + type: string + EmployeeWithId: + allOf: + - $ref: '#/components/schemas/Employee' + - type: object + required: + - id + properties: + id: + type: integer +``` + +- In the same directory, create a file named `specmatic.yaml` with the following contents: + +```yaml +version: 2 +contracts: +- consumes: + - employees.yaml +``` + +- `cd` into the `specmatic` directory and run the following command: + +{% tabs test %} +{% tab test java %} +```shell +java -jar specmatic.jar virtual-service +``` +{% endtab %} +{% tab test npm %} +```shell +npx specmatic virtual-service +``` +{% endtab %} +{% tab test docker %} +```shell +docker run -p 9000:9000 -v "${PWD}/:/usr/src/app" znsio/specmatic virtual-service +``` +{% endtab %} +{% endtabs %} + +- In a new tab, run the following curl command: + + ```shell + curl -X POST -H 'Content-Type: application/json' -d '{"name": "Jill Doe", "department": "Engineering", "designation": "Director"}' http://localhost:9000/employees + ``` + +- You should get the following response back: + + ```json + { + "name": "Jill Doe", + "department": "Engineering", + "designation": "Director", + "id": + } + ``` + +- Now in a new tab, try to query the `` received in the previous command using curl: + + ```shell + curl http://localhost:9000/employees/ + ``` + + and you will see below response, + + ```json + { + "name": "Jill Doe", + "department": "Engineering", + "designation": "Director", + "id": + } + ``` + +You can now use other restful methods such as PUT, PATCH, DELETE etc to do the CRUD operations. + +### Command Line Options + +```bash +specmatic virtual-service [-hV] [--host=] [--port=] [--examples=] +``` + +| Option | Description | +|--------|-------------| +| `-h, --help` | Show help message and exit | +| `--host=` | Host for the virtual service (default: localhost) | +| `--port=` | Port for the virtual service (default: 9000) | +| `--examples=` | Directories containing JSON examples for initial state | +| `-v, --version` | Print version information and exit | + +## Working with State + +### Default Behavior + +The virtual service maintains state automatically based on your API specifications. For example: + +1. When you create a resource using a defined endpoint, it's stored in the service's state +2. Subsequent requests will interact with the stored state according to your API specifications +3. All operations defined in your contract specifications are supported with appropriate state management + +### Pre-loading State + +You can initialize the service with pre-defined data: + +Start the service with pre-loaded examples: +```bash +specmatic virtual-service --examples="spec_file_name_examples" +``` + +Specmatic also provides GUI for generating example, checkout [Interactive Examples GUI](documentation/external_examples.html#interactive-examples-gui) + + +## Common Use Cases + +### Local Development + +```bash +# Start service on a specific port +specmatic virtual-service --port=8080 +``` + +This allows developers to work against a realistic API implementation without depending on external services. + +### Integration Testing + +```bash +# Start with pre-loaded test data +specmatic virtual-service --examples="spec_file_name_examples" +``` + +Perfect for integration tests that require consistent initial state. + +### API Design Validation + +The virtual service helps validate API design decisions early by providing a working implementation that maintains state according to your specifications. + +## Troubleshooting + +### Common Issues + +1. **Port Already in Use** + ```bash + # Solution: Use a different port + specmatic virtual-service --port=9001 + ``` + +2. **Example Files Not Loading** + - Verify JSON format is valid + - Check file permissions + - Ensure path to examples directory is correct + +3. **Resource Not Found** + - Make sure your API specification follows REST architecture + - RESTful architecture is mandatory for running stateful service + +## See Also + +- [Generating Examples Documentation](documentation/service_virtualization_tutorial.html#externalizing-example-data) +- [Contract Testing with Specmatic](documentation/contract_tests.html) From d9712cb0c51f99a987ab1414124e151574cfe408 Mon Sep 17 00:00:00 2001 From: Kaushal Vora Date: Wed, 30 Apr 2025 15:19:19 +0530 Subject: [PATCH 2/3] Updated broken links and incorporated feedbacks in VS doc --- ...stateful_service.md => virtual_service.md} | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) rename documentation/{stateful_service.md => virtual_service.md} (81%) diff --git a/documentation/stateful_service.md b/documentation/virtual_service.md similarity index 81% rename from documentation/stateful_service.md rename to documentation/virtual_service.md index 8b0a8c57..8a1e3477 100644 --- a/documentation/stateful_service.md +++ b/documentation/virtual_service.md @@ -1,16 +1,16 @@ --- layout: default -title: Stateful Service +title: Virtual Service parent: Documentation nav_order: 36 --- -# Stateful Service +# Virtual Service -- [Stateful Service](#stateful-service) +- [Virtual Service](#virtual-service) - [Pre-requisites](#pre-requisites) - [Example Usage](#example-usage) - [Command Line Options](#command-line-options) @@ -18,8 +18,8 @@ nav_order: 36 - [Default Behavior](#default-behavior) - [Pre-loading State](#pre-loading-state) - [Common Use Cases](#common-use-cases) - - [Local Development](#local-development) - - [Integration Testing](#integration-testing) + - [Local Development / API Sandbox / API Playground](#local-development--api-sandbox--api-playground) + - [Integration Testing / Ephemeral Environment Testing](#integration-testing--ephemeral-environment-testing) - [API Design Validation](#api-design-validation) - [Troubleshooting](#troubleshooting) - [Common Issues](#common-issues) @@ -27,7 +27,7 @@ nav_order: 36 -While Specmatic's service virtualization provides stateless API mocking capabilities, modern applications often require more sophisticated testing scenarios. The virtual service feature was introduced to address this need, providing stateful behavior that mirrors real-world API interactions. +While Specmatic's service virtualization provides stateless API mocking capabilities, modern applications often requires data persistance for testing complex workflows. The virtual service feature was introduced to address this need, providing stateful behavior that mirrors real-world API interactions. **Key differences from service virtualization:** - Maintains state across requests @@ -41,12 +41,10 @@ While Specmatic's service virtualization provides stateless API mocking capabili - Simulating real-world API behaviors - Development without external service dependencies -**Note:** RESTful api specification is mandatory for using Specmatic's stateful service feature. - ## Pre-requisites - Create a directory named `specmatic` in your home directory. -- Make sure you have installed Specmatic. Explore the [Getting Started](/documentation/service_virtualization_tutorial.html) page for all options for installing Specmatic. +- Make sure you have installed Specmatic. Explore the [Getting Started](../download.html) page for all options for installing Specmatic. ## Example Usage @@ -197,6 +195,14 @@ docker run -p 9000:9000 -v "${PWD}/:/usr/src/app" znsio/specmatic virtual-servic - In a new tab, run the following curl command: + ```shell + curl http://localhost:9000/employees + ``` + + Here you will see an empty response which means there is no data at this moment. + +- Now run the following curl command: + ```shell curl -X POST -H 'Content-Type: application/json' -d '{"name": "Jill Doe", "department": "Engineering", "designation": "Director"}' http://localhost:9000/employees ``` @@ -212,7 +218,14 @@ docker run -p 9000:9000 -v "${PWD}/:/usr/src/app" znsio/specmatic virtual-servic } ``` -- Now in a new tab, try to query the `` received in the previous command using curl: +- Now run the previous curl command again, + ```shell + curl http://localhost:9000/employees + ``` + + Here you will see the data which was posted using previous command. + +- Now try to query the `` received in the previous command using curl: ```shell curl http://localhost:9000/employees/ @@ -229,7 +242,7 @@ docker run -p 9000:9000 -v "${PWD}/:/usr/src/app" znsio/specmatic virtual-servic } ``` -You can now use other restful methods such as PUT, PATCH, DELETE etc to do the CRUD operations. +You can now use other CRUD methods such as PUT, PATCH, DELETE etc. ### Command Line Options @@ -259,17 +272,19 @@ The virtual service maintains state automatically based on your API specificatio You can initialize the service with pre-defined data: -Start the service with pre-loaded examples: +- By default, Specmatic looks for examples in a directory named `{specification-name}_examples` in the same location as your specification file. For instance, if your spec file is named `employee_details.yaml`, Specmatic will look for examples in the `employee_details_examples` directory. + +- Custom directory name can be passed using `--examples` flag, ```bash specmatic virtual-service --examples="spec_file_name_examples" ``` -Specmatic also provides GUI for generating example, checkout [Interactive Examples GUI](documentation/external_examples.html#interactive-examples-gui) +Specmatic also provides GUI for generating example, checkout [Interactive Examples GUI](external_examples.html#interactive-examples-gui) ## Common Use Cases -### Local Development +### Local Development / API Sandbox / API Playground ```bash # Start service on a specific port @@ -278,7 +293,7 @@ specmatic virtual-service --port=8080 This allows developers to work against a realistic API implementation without depending on external services. -### Integration Testing +### Integration Testing / Ephemeral Environment Testing ```bash # Start with pre-loaded test data @@ -308,7 +323,7 @@ The virtual service helps validate API design decisions early by providing a wor 3. **Resource Not Found** - Make sure your API specification follows REST architecture - - RESTful architecture is mandatory for running stateful service + - RESTful architecture is mandatory for running Virtual Service ## See Also From 80983219ea20b4d94a86211fb31e40d5c0c0f705 Mon Sep 17 00:00:00 2001 From: Kaushal Vora Date: Wed, 30 Apr 2025 15:55:48 +0530 Subject: [PATCH 3/3] Added example for pre-loading the virtual service --- documentation/virtual_service.md | 89 ++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/documentation/virtual_service.md b/documentation/virtual_service.md index 8a1e3477..faf484a4 100644 --- a/documentation/virtual_service.md +++ b/documentation/virtual_service.md @@ -199,31 +199,42 @@ docker run -p 9000:9000 -v "${PWD}/:/usr/src/app" znsio/specmatic virtual-servic curl http://localhost:9000/employees ``` - Here you will see an empty response which means there is no data at this moment. + Here you will see an empty response `[]` which means there is no employees data at this moment. -- Now run the following curl command: +- Now let's try to create an employee using POST request, run the following curl command: ```shell curl -X POST -H 'Content-Type: application/json' -d '{"name": "Jill Doe", "department": "Engineering", "designation": "Director"}' http://localhost:9000/employees ``` -- You should get the following response back: + The employee will get created and you will see the following response: ```json { - "name": "Jill Doe", - "department": "Engineering", - "designation": "Director", - "id": + "name": "Jill Doe", + "department": "Engineering", + "designation": "Director", + "id": } ``` -- Now run the previous curl command again, +- Now run the previous curl command again to query all the employees using GET request, ```shell curl http://localhost:9000/employees ``` - Here you will see the data which was posted using previous command. + and you will see an employee which was created previously using POST request in the response, + + ```json + [ + { + "name": "Jill Doe", + "department": "Engineering", + "designation": "Director", + "id": + } + ] + ``` - Now try to query the `` received in the previous command using curl: @@ -235,14 +246,14 @@ docker run -p 9000:9000 -v "${PWD}/:/usr/src/app" znsio/specmatic virtual-servic ```json { - "name": "Jill Doe", - "department": "Engineering", - "designation": "Director", - "id": + "name": "Jill Doe", + "department": "Engineering", + "designation": "Director", + "id": } ``` -You can now use other CRUD methods such as PUT, PATCH, DELETE etc. +This shows how Specmatic's virtual service maintains state across requests. Now you can do other CRUD operations using methods such as GET, POST, PUT, PATCH and DELETE etc. ### Command Line Options @@ -272,14 +283,58 @@ The virtual service maintains state automatically based on your API specificatio You can initialize the service with pre-defined data: -- By default, Specmatic looks for examples in a directory named `{specification-name}_examples` in the same location as your specification file. For instance, if your spec file is named `employee_details.yaml`, Specmatic will look for examples in the `employee_details_examples` directory. +- By default, Specmatic looks for examples in a directory named `{specification-name}_examples` in the same location as your specification file. For instance, if your spec file is named `employee_details.yaml`, Specmatic will look for examples in the `employees_examples` directory. + + - Create the example in `employees_examples/example.json`, + + ```json + { + "http-request": { + "method": "GET", + "path": "/employees/10" + }, + "http-response": { + "status": 200, + "body": { + "id": 10, + "name": "Jamie Rivera", + "department": "Engineering", + "designation": "Senior Software Engineer" + } + } + } + ``` + + - Start the virtual service + ```bash + specmatic virtual-service + ``` + + - Make curl request to find all the employees using below command, + ```bash + curl http://localhost:9000/employees + ``` + + you will see the below response, + ```json + [ + { + "id": 10, + "name": "Jamie Rivera", + "department": "Engineering", + "designation": "Senior Software Engineer" + } + ] + ``` + + And that's how you can pre-load / seed the data before starting the virtual service. - Custom directory name can be passed using `--examples` flag, ```bash -specmatic virtual-service --examples="spec_file_name_examples" +specmatic virtual-service --examples="" ``` -Specmatic also provides GUI for generating example, checkout [Interactive Examples GUI](external_examples.html#interactive-examples-gui) +Specmatic also provides GUI for generating examples, checkout [Interactive Examples GUI](external_examples.html#interactive-examples-gui) ## Common Use Cases