Added response model for post put and patch call
Some checks failed
Build / build (push) Has been cancelled

This commit is contained in:
Ankitkumar Satapara
2026-04-22 19:40:36 +05:30
parent 5c61fa1e53
commit 92202921a7
3 changed files with 455 additions and 7 deletions

View File

@@ -89,14 +89,46 @@ namespace Nodify.Calculator.NodeHandlers
{
var rc = info.ResponseModelClassName;
bool isList = rc.StartsWith("List<") && rc.EndsWith(">");
op.Output.Add(new ConnectorViewModel
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)
{
Title = rc,
IsInput = false,
Shape = isList ? ConnectorShape.Grid : ConnectorShape.Square,
ConnectorColor = isList ? Color.MediumSpringGreen : Color.MediumPurple,
DataType = rc
});
// 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
{
Title = rc,
IsInput = false,
Shape = isList ? ConnectorShape.Grid : ConnectorShape.Square,
ConnectorColor = isList ? Color.MediumSpringGreen : Color.MediumPurple,
DataType = rc
});
}
}
else
{

View File

@@ -437,6 +437,11 @@ namespace Nodify.Calculator
// Extract response model from 200/201 response schema
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.Output.Add("");
@@ -475,6 +480,11 @@ namespace Nodify.Calculator
// Resolve $ref references
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
var targetSchema = actualSchema;
bool isList = false;
@@ -482,6 +492,11 @@ namespace Nodify.Calculator
{
targetSchema = actualSchema.Item.ActualSchema ?? actualSchema.Item;
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
@@ -644,6 +659,20 @@ namespace Nodify.Calculator
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)
{
// e.g. /api/users/{id} + get -> GetUsersResponse

View 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": {
}
}
}
}
}