49

Is there a way to do this?

I have swashbuckle generating content for my other APIs but I don't believe it works for SignalR.

Helder Sepulveda
  • 15,500
  • 4
  • 29
  • 56
LivingOnACloud
  • 1,151
  • 1
  • 11
  • 20
  • 6
    I am greatly interested in the same thing here, although I am increasingly under the impression that SignalR is for mostly internal communication, i.e; between 1st parties. Combine this with the dynamic nature of calling SignalR, I don't think as solid of a tool as Swashbuckle will be available. I am going to experiment with a library I found that generates TypeScript interfaces, but haven't established a workflow yet. – Daniel Park Jul 06 '15 at 21:20
  • Additionally, if you want to expose a public "realtime" API, maybe a callback scheme would suit better. Something like [Facebook](https://developers.facebook.com/docs/graph-api/real-time-updates/v2.3) or [Github](https://developer.github.com/webhooks/), but this doesn't really help for simple webpage projects. – Daniel Park Jul 06 '15 at 21:22
  • I have not been able to find any tools for generating swagger documentation for SignalR, though I would love someone to point me to something that I have missed. I'm surprised this question hasn't had even an attempt at an answer. – Nathan Oct 31 '17 at 16:59
  • I mean, you can just use JSDoc comments and use any one of the tools aimed at creating documentation from those. Like say [TypeDoc](https://github.com/TypeStrong/typedoc). – Heretic Monkey Jan 29 '18 at 17:32
  • 3
    I created a prototype SignalR generator here: https://github.com/RSuter/SigSpec – Rico Suter Feb 07 '18 at 17:34

4 Answers4

20

Here's a Nuget package which can help you.

Nuget link: https://www.nuget.org/packages/SignalRSwaggerGen/

Github link: https://github.com/essencebit/SignalRSwaggerGen/wiki

First you need to decorate your SignalR hubs with attributes from SignalRSwaggerGen.Attributes namespace:

[SignalRHub]
public class SomeHub : Hub
{
}

Then you add SignalRSwaggerGen to Swagger generator:

services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo { Title = "Some API v1", Version = "v1" });
    // here some other configurations maybe...
    options.AddSignalRSwaggerGen();
});

For more information please refer to Github documentation.

dorin.mocan
  • 219
  • 2
  • 5
  • 5
    Newest releases of the package brings auto-discover option, so that you do not need to decorate the methods and their arguments with attributes, which makes the code less noisy. Also there is support for multiple Swagger docs and other neat stuff. – dorin.mocan Aug 04 '21 at 20:47
  • 2
    Thanks for this package. It is not clear to me from Wiki that the need to decorate methods and their arguments is no longer required. Maybe I miss something but can you update Wiki accordingly if that is so? – ruzgarustu Dec 14 '21 at 10:49
  • 3
    @ruzgarustu , updated Wiki. Sorry for confusing you, and thanks for feedback! – dorin.mocan Dec 16 '21 at 19:39
  • @dorin.mocan Just checked your package, but there's no mention about the AutoDiscover functionality... Any docs I check on how to config it please? – rumblefx0 Jul 05 '22 at 12:13
  • 1
    @rumblefx0, please read the xml documentation. I added xml comments across the entire package, so nothing left without comments. If the documentation is not clear enough, you could just play around with the options of AutoDiscover and see how it behaves. In a nutshell, if you have a hub and you want hub methods to be discovered automatically without decorating them with attributes, you specify the appropriate AutoDiscover option. Let me know in case you couldn't figure out how to use it. I'll help. – dorin.mocan Jul 07 '22 at 07:03
  • I've tried to use it with `AbpHub`-inherited class (**ABP framework** that we use), but endpoint did not show up... I don't know why, I followed the recomendations at their site. BTW, `AbpHub` class is inherited from `Hub`. – Alexander Dec 27 '22 at 22:03
  • @Alexander, could you please raise an issue on GitHub and provide more details and code snippets maybe? I'll investigate and help solve your problem. – dorin.mocan Dec 29 '22 at 07:25
  • I wanted to expose the definition of a hub with only 1 event so that the client can autogenerate the used types. The hub and event showed up, but the event lost its type information. :( – AyCe Mar 10 '23 at 07:00
  • @AyCe please raise an issues on GitHub and share some more details. I'll try help asap. – dorin.mocan Mar 12 '23 at 11:08
3

I successfully used SigSpec for this purpose as suggested by the comment.

I had to tinker a little but it did the job.

Yennefer
  • 5,704
  • 7
  • 31
  • 44
  • Hi, unfortunately, I no longer have access to the sources of that project. I remember that things were not right in the ui (at least in the version we had), but we managed to integrate the produced json in the UI like for other controllers. Our purpose was to document the hub in some way, and that trick (making it appear as a controller) and few other tricks did the job. (I known this is not an answer, and probably not helpful) – Yennefer Aug 25 '20 at 10:12
1

I search a lot and I found this Nuget package SignalRSwaggerGen but the documentation is misleading and not clear as you thought but it's a great package for documenting Hubs for SignalR in Swagger and will provide here snippets I hope they add a clear documentation.

  • Put the data annotation that says that's a SignalR Hub just for Swagger.

      /// <summary>
      /// Authorized Presence Hub that's accessed via 'hubs/presence'.
      /// </summary>
      [SignalRHub]
      [Authorize]
      public sealed class PresenceHub : Hub {}
    
  • Put the data annotation that says the name of the method that you will use the name for the method to be used.

      /// <summary>
      /// UserIsOnline Hub method method that's used for tracking the online users.
      /// <returns>Returns the full name with any user that's just got online.</returns>
      /// </summary>
      [SignalRMethod("UserIsOnline")]
      public override async Task OnConnectedAsync()
      {
          await Clients.Others.SendAsync("UserIsOnline", Context.User.GetUserFullName());
      }
    
  • to make the XML documenation take effect you have to put this in Swagger.

      builder.Services.AddSwaggerGen(opts =>
      {
          var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
          var xmlCommentsFullPath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFile);
    
          opts.IncludeXmlComments(xmlCommentsFullPath);
    
          opts.AddSignalRSwaggerGen(_ =>
          {
              _.UseHubXmlCommentsSummaryAsTagDescription =  true;
              _.UseHubXmlCommentsSummaryAsTag = true;
              _.UseXmlComments(xmlCommentsFullPath);
          });
      });
    

and make sure to add <GenerateDocumentationFile>true<GenerateDocumentationFile> as the following:-

    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <GenerateDocumentationFile>true</GenerateDocumentationFile>
        <NoWarn>$(NoWarn);1591</NoWarn>
    </PropertyGroup>
Mahmmoud Kinawy
  • 551
  • 4
  • 11
  • No need to add anotations to hub methods. They'll be scanned automatically. Annotations are needed only when you need some specific configuration for a specific method. – dorin.mocan Apr 28 '23 at 18:22
  • I too needed extra parameters to make the xml-comments work. Also, if you want to give the hubs another version/page in swagger, you need to add documentNames inside the ```SignalRHub``` attribute: ```[SignalRHub(documentNames: new string[] { "hubs" })] [ApiVersion("hubs")]``` But great libary nonetheless! – Jannick Breunis Aug 25 '23 at 13:15
-5

Assuming that you're using Asp.NET Core, custom documentation can be injected at startup time.

In your Startup.ConfigureServices you should already have a Swagger section:

services.AddSwaggerGen(c =>
{
    ...
})

Just add a custom XML file to Swagger documentation:

services.AddSwaggerGen(c =>
{
    c.IncludeXmlComments("custom_doc.xml");
})

where custom_doc.xml is a standard C# XML documentation file.

Mario Cianciolo
  • 1,223
  • 10
  • 17