vaclavnovotny / NSwag.Examples

NSwag processor to programmatically define strongly-typed examples for response and request parameters.
MIT License
13 stars 11 forks source link

Request Body automatic addition of examples defined for properties #26

Closed toutas closed 2 months ago

toutas commented 2 months ago

I have the following request body class:

public class PostTaskOrderEstimateCommand : IRequestWrapper<TaskOrderDto>
{
    public string? Wkt { get; set; }
    public GeoJsonGeometryDto? GeoJson { get; set; }
}

I have defined an example for PostTaskOrderCommand:

public class PostTaskOrderEstimateCommandExample : IExampleProvider<PostTaskOrderEstimateCommand>
{
    public PostTaskOrderEstimateCommand GetExample()
    {
        PostTaskOrderEstimateCommand result = new PostTaskOrderEstimateCommand
        {
            Wkt = "GEOMETRYCOLLECTION (MULTIPOLYGON (((9.157104 55.976872, 9.157104 56.12106, 9.371338 56.12106, 9.371338 55.976872, 9.157104 55.976872)), ((9.030762 56.362207, 8.948364 56.295205, 9.041748 56.26166, 9.140625 56.286059, 9.030762 56.362207))), POLYGON ((10.288696 56.114936, 10.05249 56.133307, 9.986572 56.0475, 10.101929 56.004524, 10.288696 56.114936)), POLYGON ((11.640015 55.615589, 11.876221 55.590763, 11.694946 55.491304, 11.640015 55.615589)), POLYGON ((11.65 55.62, 11.651 55.62, 11.65 55.621, 11.65 55.62)), MULTIPOLYGON (((11.652 55.622, 11.653 55.622, 11.652 55.623, 11.652 55.622)), ((11.654 55.624, 11.655 55.624, 11.654 55.625, 11.654 55.624))))",
        };

        return result;
    }
}

The documentation that is generated shows the PostTaskOrderEstimateCommandExampleas expected, but I have another example defined for GeoJsonGeometryDto:

public class GeoJsonGeometryDtoExample : IExampleProvider<GeoJsonGeometryDto>
{
    public GeoJsonGeometryDto GetExample()
    {
        var result = new GeoJsonGeometryDto()
        {
            Type = "GeometryCollection",
            Geometries =
            [
                new GeoJsonGeometryDto()
                {
                    Type = "MultiPolygon",
                    Coordinates = new double[][][][]
                    {
                        [
                            [
                                [9.157104, 55.976872],
                                [9.157104, 56.12106],
                                [9.371338, 56.12106],
                                [9.371338, 55.976872],
                                [9.157104, 55.976872]
                            ],
                            [
                                [9.030762, 56.362207],
                                [8.948364, 56.295205],
                                [9.041748, 56.26166],
                                [9.140625, 56.286059],
                                [9.030762, 56.362207]
                            ]
                        ]
                    },
                },
                new GeoJsonGeometryDto()
                {
                    Type = "MultiPolygon",
                    Coordinates = new double[][][][]
                    {
                        [
                            [
                                [11.652, 55.622],
                                [11.653, 55.622],
                                [11.652, 55.623],
                                [11.652, 55.622]
                            ],
                            [
                                [11.654, 55.624],
                                [11.655, 55.624],
                                [11.654, 55.625],
                                [11.654, 55.624]
                            ]
                        ]
                    },
                },
                new GeoJsonGeometryDto()
                {
                    Type = "Polygon",
                    Coordinates = new double[][][]
                    {
                        [
                            [10.288696, 56.114936],
                            [10.05249, 56.133307],
                            [9.986572, 56.0475],
                            [10.101929, 56.004524],
                            [10.288696, 56.114936]
                        ]
                    },
                },
                new GeoJsonGeometryDto()
                {
                    Type = "Polygon",
                    Coordinates = new double[][][]
                    {
                        [
                            [11.640015, 55.615589],
                            [11.876221, 55.590763],
                            [11.694946, 55.491304],
                            [11.640015, 55.615589]
                        ]
                    },
                },
                new GeoJsonGeometryDto()
                {
                    Type = "Polygon",
                    Coordinates = new double[][][]
                    {
                        [
                            [11.650, 55.620],
                            [11.651, 55.620],
                            [11.650, 55.621],
                            [11.650, 55.620]
                        ]
                    },
                },
            ]
        };

        return result;
    }
}

Is there any way to force/nudge this example to be used when the GeoJsonGeometryDto is a property on a body?

Currently the documentation just shows:

{
"Wkt": "GEOMETRYCOLLECTION (MULTIPOLYGON (((9.157104 55.976872, 9.157104 56.12106, 9.371338 56.12106, 9.371338 55.976872, 9.157104 55.976872)), ((9.030762 56.362207, 8.948364 56.295205, 9.041748 56.26166, 9.140625 56.286059, 9.030762 56.362207))), POLYGON ((10.288696 56.114936, 10.05249 56.133307, 9.986572 56.0475, 10.101929 56.004524, 10.288696 56.114936)), POLYGON ((11.640015 55.615589, 11.876221 55.590763, 11.694946 55.491304, 11.640015 55.615589)), POLYGON ((11.65 55.62, 11.651 55.62, 11.65 55.621, 11.65 55.62)), MULTIPOLYGON (((11.652 55.622, 11.653 55.622, 11.652 55.623, 11.652 55.622)), ((11.654 55.624, 11.655 55.624, 11.654 55.625, 11.654 55.624))))",
"GeoJson": null
}

but I would like the GeoJson example to fill out the GeoJson property for the example.

vaclavnovotny commented 2 months ago

Hello @toutas! It is possible to "nudge" GeoJsonGeometryDtoExample into the PostTaskOrderEstimateCommandExample by using dependency injection supported by NSwag.Examples. Consider following approach:

public class PostTaskOrderEstimateCommandExample : IExampleProvider<PostTaskOrderEstimateCommand>
{
    private readonly IExampleProvider<GeoJsonGeometryDtoExample> _geoJsonExample;

    public PostTaskOrderEstimateCommandExample(IExampleProvider<GeoJsonGeometryDtoExample> geoJsonExample) {
        _geoJsonExample = geoJsonExample;
    }

    public PostTaskOrderEstimateCommand GetExample()
    {
        PostTaskOrderEstimateCommand result = new PostTaskOrderEstimateCommand
        {
            Wkt = "GEOMETRYCOLLECTION (MULTIPOLYGON (((9.157104 55.976872, 9.157104 56.12106, 9.371338 56.12106, 9.371338 55.976872, 9.157104 55.976872)), ((9.030762 56.362207, 8.948364 56.295205, 9.041748 56.26166, 9.140625 56.286059, 9.030762 56.362207))), POLYGON ((10.288696 56.114936, 10.05249 56.133307, 9.986572 56.0475, 10.101929 56.004524, 10.288696 56.114936)), POLYGON ((11.640015 55.615589, 11.876221 55.590763, 11.694946 55.491304, 11.640015 55.615589)), POLYGON ((11.65 55.62, 11.651 55.62, 11.65 55.621, 11.65 55.62)), MULTIPOLYGON (((11.652 55.622, 11.653 55.622, 11.652 55.623, 11.652 55.622)), ((11.654 55.624, 11.655 55.624, 11.654 55.625, 11.654 55.624))))",
        };
        GeoJson = _geoJsonExample.GetExample();

        return result;
    }
}

You can resolve your already defined example of GeoJsonGeometry from the constructor and use the available method GetExample. Does this work for you?

toutas commented 2 months ago

@vaclavnovotny thank you for your suggestion, it worked out perfectly!

I made a mistake in defining the IExampleProvider to retrieve using DI, but it works exactly as I was hoping.

Thank you for helping out, just started checking out your solution for setting up examples and I'm loving it so far.