Added response model for post put and patch call
Some checks failed
Build / build (push) Has been cancelled
Some checks failed
Build / build (push) Has been cancelled
This commit is contained in:
@@ -89,6 +89,37 @@ namespace Nodify.Calculator.NodeHandlers
|
|||||||
{
|
{
|
||||||
var rc = info.ResponseModelClassName;
|
var rc = info.ResponseModelClassName;
|
||||||
bool isList = rc.StartsWith("List<") && rc.EndsWith(">");
|
bool isList = rc.StartsWith("List<") && rc.EndsWith(">");
|
||||||
|
var primitives = new[] { "string", "int", "double", "float", "bool", "decimal", "long", "datetime" };
|
||||||
|
var innerType = isList ? rc.Substring(5, rc.Length - 6) : rc;
|
||||||
|
bool isPrimitive = primitives.Contains(innerType.ToLower());
|
||||||
|
|
||||||
|
if (isPrimitive && !isList)
|
||||||
|
{
|
||||||
|
// Primitive response (e.g. int, string, bool)
|
||||||
|
op.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = rc,
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Circle,
|
||||||
|
ConnectorColor = ConnectorViewModel.GetColorForType(rc),
|
||||||
|
DataType = rc.ToLower()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (isList && isPrimitive)
|
||||||
|
{
|
||||||
|
// List of primitives (e.g. List<string>)
|
||||||
|
op.Output.Add(new ConnectorViewModel
|
||||||
|
{
|
||||||
|
Title = rc,
|
||||||
|
IsInput = false,
|
||||||
|
Shape = ConnectorShape.Grid,
|
||||||
|
ConnectorColor = Color.MediumSpringGreen,
|
||||||
|
DataType = rc
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Model or List<Model>
|
||||||
op.Output.Add(new ConnectorViewModel
|
op.Output.Add(new ConnectorViewModel
|
||||||
{
|
{
|
||||||
Title = rc,
|
Title = rc,
|
||||||
@@ -98,6 +129,7 @@ namespace Nodify.Calculator.NodeHandlers
|
|||||||
DataType = rc
|
DataType = rc
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
op.Output.Add(new ConnectorViewModel
|
op.Output.Add(new ConnectorViewModel
|
||||||
|
|||||||
@@ -437,6 +437,11 @@ namespace Nodify.Calculator
|
|||||||
|
|
||||||
// Extract response model from 200/201 response schema
|
// Extract response model from 200/201 response schema
|
||||||
var responseModelName = ExtractResponseModel(method.Value, path.Key, method.Key, createdModels);
|
var responseModelName = ExtractResponseModel(method.Value, path.Key, method.Key, createdModels);
|
||||||
|
|
||||||
|
// Fallback: if no explicit response model, use request body model for POST/PUT/PATCH
|
||||||
|
if (string.IsNullOrEmpty(responseModelName) && !string.IsNullOrEmpty(ovmodel.RequestBodyModelClassName))
|
||||||
|
responseModelName = ovmodel.RequestBodyModelClassName;
|
||||||
|
|
||||||
ovmodel.ResponseModelClassName = responseModelName;
|
ovmodel.ResponseModelClassName = responseModelName;
|
||||||
|
|
||||||
ovmodel.Output.Add("");
|
ovmodel.Output.Add("");
|
||||||
@@ -475,6 +480,11 @@ namespace Nodify.Calculator
|
|||||||
// Resolve $ref references
|
// Resolve $ref references
|
||||||
var actualSchema = schema.ActualSchema ?? schema;
|
var actualSchema = schema.ActualSchema ?? schema;
|
||||||
|
|
||||||
|
// Handle primitive response types (string, int, bool, etc.)
|
||||||
|
var primitiveType = MapPrimitiveSchemaType(actualSchema);
|
||||||
|
if (!string.IsNullOrEmpty(primitiveType))
|
||||||
|
return primitiveType;
|
||||||
|
|
||||||
// Resolve the actual item schema for arrays
|
// Resolve the actual item schema for arrays
|
||||||
var targetSchema = actualSchema;
|
var targetSchema = actualSchema;
|
||||||
bool isList = false;
|
bool isList = false;
|
||||||
@@ -482,6 +492,11 @@ namespace Nodify.Calculator
|
|||||||
{
|
{
|
||||||
targetSchema = actualSchema.Item.ActualSchema ?? actualSchema.Item;
|
targetSchema = actualSchema.Item.ActualSchema ?? actualSchema.Item;
|
||||||
isList = true;
|
isList = true;
|
||||||
|
|
||||||
|
// Check if array items are primitive
|
||||||
|
var itemPrimitive = MapPrimitiveSchemaType(targetSchema.ActualSchema ?? targetSchema);
|
||||||
|
if (!string.IsNullOrEmpty(itemPrimitive))
|
||||||
|
return $"List<{itemPrimitive}>";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve again in case of nested $ref
|
// Resolve again in case of nested $ref
|
||||||
@@ -644,6 +659,20 @@ namespace Nodify.Calculator
|
|||||||
return "string";
|
return "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the C# primitive type name if the schema is a simple type (string, int, etc.),
|
||||||
|
/// or null if it's an object/complex type that needs a model class.
|
||||||
|
/// </summary>
|
||||||
|
private static string? MapPrimitiveSchemaType(NJsonSchema.JsonSchema schema)
|
||||||
|
{
|
||||||
|
var type = schema.Type;
|
||||||
|
if (type.HasFlag(NJsonSchema.JsonObjectType.String)) return "string";
|
||||||
|
if (type.HasFlag(NJsonSchema.JsonObjectType.Integer)) return "int";
|
||||||
|
if (type.HasFlag(NJsonSchema.JsonObjectType.Number)) return "double";
|
||||||
|
if (type.HasFlag(NJsonSchema.JsonObjectType.Boolean)) return "bool";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static string DeriveClassName(string path, string httpMethod)
|
private static string DeriveClassName(string path, string httpMethod)
|
||||||
{
|
{
|
||||||
// e.g. /api/users/{id} + get -> GetUsersResponse
|
// e.g. /api/users/{id} + get -> GetUsersResponse
|
||||||
|
|||||||
387
Examples/Nodify.Calculator/swagger.json
Normal file
387
Examples/Nodify.Calculator/swagger.json
Normal file
@@ -0,0 +1,387 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.0.1",
|
||||||
|
"info": {
|
||||||
|
"title": "Simple Pizza Api",
|
||||||
|
"description": "A simple ASP.NET Core Web Api application with CRUD including Patch that allows you to work with pizza data",
|
||||||
|
"contact": {
|
||||||
|
"name": "Kathleen West",
|
||||||
|
"url": "https://portfolio.katiegirl.net",
|
||||||
|
"email": "hello.kathleen.west@gmail.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT License",
|
||||||
|
"url": "https://opensource.org/licenses/MIT"
|
||||||
|
},
|
||||||
|
"version": "v1"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/error": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Error"
|
||||||
|
],
|
||||||
|
"operationId": "Error",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/Pizza": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Pizza"
|
||||||
|
],
|
||||||
|
"summary": "Get all the pizza model objects in memory",
|
||||||
|
"operationId": "GetAll",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Pizza"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Pizza"
|
||||||
|
],
|
||||||
|
"summary": "Creates a pizza and automatically assigns a unique identifier (int)",
|
||||||
|
"operationId": "Create",
|
||||||
|
"requestBody": {
|
||||||
|
"description": "(Pizza) pizza model object",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Pizza"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Created"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/Pizza/{id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Pizza"
|
||||||
|
],
|
||||||
|
"summary": "Get one specific pizza given a unique identifier (int)",
|
||||||
|
"operationId": "Get",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"description": "(int) unique identifier of the pizza",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Success",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Pizza"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"Pizza"
|
||||||
|
],
|
||||||
|
"summary": "Updates a specific pizza given a unique identifier (int), if it exists",
|
||||||
|
"operationId": "Update",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"description": "(int) unique identifier of the pizza",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "(Pizza) pizza to delete",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Pizza"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patch": {
|
||||||
|
"tags": [
|
||||||
|
"Pizza"
|
||||||
|
],
|
||||||
|
"summary": "Updates properties of a specific pizza given a unique identifier (int), if it exists",
|
||||||
|
"operationId": "Patch",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"description": "(int) unique identifier of the pizza",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "(JsonPatchDocument) patch of operations",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/Operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"Pizza"
|
||||||
|
],
|
||||||
|
"summary": "Delete a specific pizza given a unique identifier, if it exists",
|
||||||
|
"operationId": "Delete",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"description": "(int) identifier of the pizza",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/errorDemo/{id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Pizza"
|
||||||
|
],
|
||||||
|
"summary": "Demo of Custom Error Handling for Get Operation",
|
||||||
|
"operationId": "GetErrorDemo",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"description": "(int) unique identifier of the pizza",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"500": {
|
||||||
|
"description": "Server Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Operation": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"value": {
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"op": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"from": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"Pizza": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Unique Identifier (int) \r\nfor Pizza",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the Pizza (string)",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"isGlutenFree": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Is this Pizza Gluten Free\r\n(bool true --\u003E yes)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "Simple Pizza"
|
||||||
|
},
|
||||||
|
"ProblemDetails": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"detail": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"instance": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user