Reputation: 1567
I use a standard APIResponse Object Interface for all of my REST APIs.
public interface IAPIResponse
{
IAPIError Error { get; set; }
IEnumerable<dynamic> Results { get; set; }
void AddResult(string groupName, object data);
}
Here is how I use the standard APIResponse object.
public async Task<IActionResult> Get()
{
try
{
var response = new UsersGetResponse {
Users = await _someService.GetAll()};
_apiResponse.AddResult("UsersGetResponse", response );
return new ObjectResult(_apiResponse);
}
catch (Exception ex)
{
_apiResponse.Error = new APIError(ex.Message, 500);
return new ObjectResult(_apiResponse);
}
}
The call to _someSerice.GetAll() returns a list of the following User Objects.
public interface IUser
{
string Id { get; set; }
bool IsAdmin { get; }
string Name { get; set; }
string Email { get; set; }
}
Which is an attribute of the parent class UsersGetResponse
public class UsersGetResponse
{
public IList<User> Users { get; set;}
}
This will produce the following JSON.
{
"error": null,
"results": [
{
"UsersGetResponse": {
"Users": [
{
"id": 171161,
"isAdmin" : true,
"name": "Dave Smith",
"email": "[email protected]"
},
{
"id": 171162,
"isAdmin" : false,
"name": "Jane Doe",
"email": "[email protected]"
}
]
}
}
]
}
If I use the ProducedResponseType annotation like so.
[ProducesResponseType(typeof(IAPIResponse), StatusCodes.Status200OK)]
I only get the following Example JSON in swagger.
{
"error": {
"message": "string",
"number": 0
},
"results": [
{}
]
}
I'm trying to see if there is a way to properly communicate to the consumers of my API that I have a standard APIResponse Object with Dynamic results that have specific Objects like UsersGetResponse.
Upvotes: 0
Views: 4328
Reputation: 391
Without fully understanding the scope of what you are trying to do, I will not be able to give you a complete solution. However, with the info that you have provided, this is what you should do:
public sealed class APIResponse<T>
{
IAPIError Error { get; set; }
T Results { get; set; }
}
public async Task<IActionResult> Get()
{
var response = new ApiResponse<<IEnumerable<User>>>();
try
{
var data = await _someService.GetAll();
response.Result = data;
return Ok(response);//returns 200 status code
}
catch (Exception ex)
{
response.Error = new APIError(ex.Message, 500);
return BadRequrest(response);
}
}
You can then annotate like this:
[ProducesResponseType(typeof(APIResponse<IEnumerable<User>>), StatusCodes.Status200OK)]
Hope this helps.
Upvotes: 1
Reputation: 391
This is because you are using dynamic type. Swagger does not recognize any "properties" on that type. If you use a concrete type or an interface instead, swagger will show you the properties on that object.
Upvotes: 0