Web Api - Auto generating request samples using ApiExplorer
Asked Answered
E

1

5

Is there a way to make ApiExplorer auto generate request samples?

I tried using:

config.SetActualResponseType(typeof(SomeType), "ControllerName", "Post"); 

in HelpPageConfig.cs, but 2 problems came up:

  1. it requires me to define specific types for specific controllers and actions and I'm looking for something more generic which will not require adding\changing code if a new controller\type was added.

  2. I can only use one type per controller\action, so I can't generate a full request sample for an action that receives 2 composite types in it's request body.

Any ideas on how to solve\approach these issues?

Evangelina answered 15/9, 2013 at 9:41 Comment(1)
ApiExplorer doesn't generate samples, but the HelpPage pacakge has code which generates it. Also SetActualResponseType is useful in scenarios when let's say you have a return type like HttpResponseMessage on the action. Since this is masking the actual returning type that you would be returning, SetActualResponseType guides HelpPage sample generator to know the type and generate samples for it. You need not use SetActualResponseType if your action returns a type SomeType. Regarding receives 2 composite types: Web API allows only 1 parameter to come from body, so can you clarify?Sather
R
8

As Kiran Challa mentioned in a comment on the OP, the auto generation of samples is part of the Help Pages package, and not the ApiExplorer interface.

For question #1 you're looking to define examples for composite objects wherever they are used. You do this via the SetSampleObjects method in your Help Pages configuration. For example, this is from my HelpPageConfig.Register method:

config.SetSampleObjects(new Dictionary<Type, object>
{
    {typeof(CompositeType1), ModelExamples.GenerateExample<CompositeType1>()},
    {typeof(CompositeType2), ModelExamples.GenerateExample<CompositeType2>()},
    {typeof(CompositeType3), ModelExamples.GenerateExample<CompositeType3>()},
});

where ModelExamples.GenerateExample is a static method/class I use to create example objects of the specified type, keeping this section clean and concise. The above will cause your Help Pages documentation to use your generated examples for return types of CompositeType1, CompositeType2, and CompositeType3.

This brings us to question #2. I assume you're talking about return types consisting of multiple composite types such as:

List<CompositeType1>

or

Tuple<CompositeType1,CompositeType2>

It's not sufficient to have the generated models as above since the Help Pages logic only checks the type of the return as a whole before deciding whether to use your model or generate a generic example. So you need to add entries like this:

config.SetSampleObjects(new Dictionary<Type, object>
{
    {
        typeof(List<CompositeType1>),
        ModelExamples.GenerateExample<List<CompositeType1>>()
    },
    {
        typeof(Tuple<CompositeType1,CompositeType2>),
        ModelExamples.GenerateExample<Tuple<CompositeType1,CompositeType2>>()
    },
});

Now, if you are are using HttpResponseMessage for any of your return types, that's when you use config.SetActualResponseType() like this:

config.SetActualResponseType(
    typeof(List<CompositeType1>), 
    "Foo",
    "ApiMethodA");
config.SetActualResponseType(
    typeof(Tuple<CompositeType1,CompositeType2>), 
    "Bar",
    "ApiMethodB");

TL;DR / Conclusion: The combination of config.SetSampleObjects and config.SetActualResponseType will let you customize what example objects look like in the Help Pages auto-generated documentation in general, and allow you to specify which example objects the response for each method should use.

2016 Edit Responding to a comment. The ModelExamples is just creating sample objects of the specified type. This can be done many ways, but here is one way:

public static class ModelExamples
{
    public static T GenerateExample<T>()
    {
        var retval = default(T);

        if (typeof(T) == typeof(ActionResult))
        {
            var value = ActionResult.Success;
            retval = (T)(object)value;
        }

        // ... whatever other types you handle go here ...

        return retval;
    }
}
Rhinehart answered 13/11, 2013 at 17:20 Comment(2)
Could you post a sample of your ModelExamples class?Sheepish
I added a snippet in response to your request AhehoRhinehart

© 2022 - 2024 — McMap. All rights reserved.