As Jeremy Fiel confirmed, there is no command to create individual docs from a split. So here is the code I wrote to accomplish this. The Split command creates a document "openapi.json". This document contains all the paths (endpoints) and the $ref to all the components. The key is to build an openapi spec document for each endpoint.
My openapi.json doc started with the info block like this
"openapi": "3.0.1",
"info": {
"title": "TC.Enterprise.eServicesOrchestrator.WebService",
"description": "TC.Enterprise.eServicesOrchestrator.WebService v1.0.0",
"version": "1.0.0"
Then taking each path
like this
"/BestFitPharmacy/{programId}": {
"$ref": "paths/BestFitPharmacy_{programId}.json"
I combined them to create an openapi spec document.
{
"openapi":"3.0.1","info":{
"title":"TC.Enterprise.eServicesOrchestrator.WebService",
"description":"TC.Enterprise.eServicesOrchestrator.WebService v1.0.0","version":"1.0.0"
},
"paths":{
"/BestFitPharmacy/{programId}":{
"$ref": "paths/BestFitPharmacy_{programId}.json"
}
}
}
This document can then be processed by the redocly build-docs
command and it will generate the openapi html document. The whole process I created, from start to finish, is as follows:
Get the Swagger.json document generated at startup and save it.
Run the redocly split
command to generate the openapi.json doc, paths and components folders.
Using the paths in openapi.json build individual openapi spec docs for each endpoint.
Those documents can then be run through the redocly bundle-docs
command to create the html documents.
The first two are pretty straight forward. Here is the code I wrote to accomplish #3 &4. GenerateSwaggerDocs()
creates the new openapi spec docs, which then calls the RunBundleCommand()
to create the HTML doc. I have 78 endpoints and the whole thing takes about a minute.
I'm not running the script from the same folder the docs are being generated. I'm doing that because I want the script to be in source control but not the resulting swagger docs.
public static async Task GenerateSwaggerDocs ()
{
var sourceDir = Directory.GetCurrentDirectory();
var destinationDir = "../bin/swagger/split/";
var masterDoc = "../bin/swagger/split/openapi.json";
var masterJson = JsonArray.Parse(File.ReadAllText(masterDoc));
var apiText = masterJson["openapi"];
var info = masterJson["info"];
var paths = masterJson["paths"];
var jsonHeader = string.Concat("openapi\":", apiText.ToJsonString(), ",", "\"info\":", info.ToJsonString(),",");
JObject pathObject = new();
if (paths != null)
{
pathObject = JObject.Parse(paths.ToJsonString());
}
var result = pathObject.SelectTokens("data.symbols");
if (!Directory.Exists(destinationDir))
{
Directory.CreateDirectory(destinationDir);
}
foreach (var x in pathObject)
{
var newJson = string.Concat($"{{\"{jsonHeader} \"paths\":{{", $"\"{x.Key}\":", $"{x.Value}}}}}");
//TODO: This is just to monitor the progress. It can take a minute or two, to write all the files. This can be removed once calling this is moved from Start.cs to a PS script.
Console.WriteLine(newJson);
var fileName = x.Key.Replace("{", "").Replace("}","").Replace("/","_").TrimStart('_');
await File.WriteAllTextAsync($"{destinationDir}{fileName}.json", newJson).ConfigureAwait(false);
RunBundleCommand(fileName);
}
}
private static void RunBundleCommand(string fileName)
{
string output = string.Empty;
if(File.Exists($"../bin/swagger/split/{fileName}.json"))
{
var args = $"bundle \"../bin/swagger/split/{fileName}.json\" --output=\"../bin/swagger/finalDocs/{fileName}.json\"";
using (var process = new Process())
{
process.StartInfo = new ProcessStartInfo()
{
WorkingDirectory = Directory.GetCurrentDirectory(),
FileName = "redocly.cmd",
Arguments = args,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
try
{
process.Start();
process.WaitForExit();
if (process.StandardOutput.ReadToEnd() != string.Empty)
output = process.StandardOutput.ReadToEnd();
else if (process.StandardError.ReadToEnd() is { } error)
output = error;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
RunBuild_DocsCommand(fileName);
}
}