Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve swagger docs support #287

Merged
merged 14 commits into from
Jul 5, 2022
Merged

Improve swagger docs support #287

merged 14 commits into from
Jul 5, 2022

Conversation

daddykotex
Copy link
Contributor

Address: #150

Also address a security issue with the url query param that was previously required.

The result looks like:
Screen Shot 2022-06-30 at 10 41 39
Screen Shot 2022-06-30 at 10 41 53
Screen Shot 2022-06-30 at 10 42 03

I'm still unsure about the user experience around smithy4s.http4s.swagger.multipleDocs[IO](HelloWorldService, PizzaAdminService)(path = "docs")

Let me know what you think

@daddykotex daddykotex marked this pull request as draft June 30, 2022 19:50
@daddykotex
Copy link
Contributor Author

I'll mark as draft, just because I would need to update doc but will only do so when we agree on the UI to build the swagger http4s route

@Baccata
Copy link
Contributor

Baccata commented Jul 1, 2022

This looks great ! To improve the UX, we can use the partially-applied pattern :

def docs : PartiallyAppliedDocs = new PartiallyAppliedDocs("docs") 

class PartiallyAppliedDocs(path: Path) {
   def atPath(path: Path) = new PartiallyAppliedDocs(path)
   def apply(first: HasId, rest: HasId*)= ...
} 

That wouldn't be breaking the sources of most current usage I think.

@@ -28,5 +28,5 @@ trait TestCompat { self: BaseIOSuite =>
}

def docs(path: String) =
Docs[IO](service, path, swaggerUiPath = "swaggerui")
Docs.multiple[IO](path, swaggerUiPath = "swaggerui")(service)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might as well remove the multiple method altogether and just document the new way of wiring things up 😄

Also we might want to make the swaggerUiPath configurable in the PartiallyApplied construct

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we might want to make the swaggerUiPath configurable in the PartiallyApplied construct

I started doing it, but I found that cumbersome. I figured, if someone needs to go all the way down and customize the swagger ui, they can use Docs.build[IO](path, swaggerUiPath = "swaggerui")(service) like in this TestCompat

note build is the new name I used instead of multiples`


will update the docs, but not much has changed from a user point of view

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will update the docs, but not much has changed from a user point of view

A screenshot of the drop-down menu added to the docs would be nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do that

@daddykotex daddykotex marked this pull request as ready for review July 4, 2022 14:36
@daddykotex
Copy link
Contributor Author

daddykotex commented Jul 4, 2022

Updated docs:

updated: see below

@daddykotex
Copy link
Contributor Author

wow, chrome screenshot does not like that

v2:
localhost_3000_smithy4s_docs_protocols_simple-rest-json_docs (1)

@Baccata
Copy link
Contributor

Baccata commented Jul 4, 2022

Right, so great work 👍 , but I'm gonna nitpick at the fact that there are too many ways to create doc routes. Comments incoming

@Baccata Baccata marked this pull request as draft July 4, 2022 15:58
@@ -50,21 +55,19 @@ private[smithy4s] object Compat {
}

trait DocsCompanion extends SwaggerUiInit {
def apply[F[_]](
hasId: HasId,
def build[F[_]](
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should disappear plainly and simply in favour of "smart-setters" in the PartiallyApplied construct.

val docs = Docs[F](hasId, path)
docs.routes
def docs: PartiallyAppliedDocs = new PartiallyAppliedDocs("docs")
def atPath(path: String): PartiallyAppliedDocs =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should disappear plainly and simply in favour of "smart-setters" in the PartiallyApplied construct.

def atPath(path: String): PartiallyAppliedDocs =
new PartiallyAppliedDocs(path)

class PartiallyAppliedDocs(path: String) {
Copy link
Contributor

@Baccata Baccata Jul 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should receive smart setters to virtually "mutate" (read, immutable copy) of the path value and the swaggerUiPath value. The apply method should be the last thing the user call and should create the HttpRoutes

Additionally, it'd be great if some tests could be added to exercise the smart setters, in order to ensure that the API is the same across CE versions. The only thing that needs specialisation (in tests) is the creation of the PartiallyApplied, which should require a Blocker in CE2. The rest can be CE-version-agnostic

PermanentRedirect(
Location(Uri.unsafeFromString(s"/$path/index.html?url=/$jsonSpec"))
)
Found(Location(Uri.unsafeFromString(s"/$path/index.html")))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious (and also somewhat illiterate when it comes to 3xx statuses) : can you tl;dr the "why" of changing the status ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it because 308 is cached very aggressively (forever) and thus you can't change a redirect afterwards. But I can revert that, I don't have an opinion on the matter. On quick look at MDN suggest that it's mostly for SEO purposes.

In my case, it was annoying because I had run a smithy project locally before, accessed the docs (for say PizzaAdmin) and now my browser was always redirecting me to this old url with pizza spec in it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes total sense, thanks !

@Baccata Baccata marked this pull request as ready for review July 5, 2022 07:41
@Baccata
Copy link
Contributor

Baccata commented Jul 5, 2022

@daddykotex I made some changes to improve the UX a little, but it's great work 👍

@Baccata Baccata merged commit 1ba3a4f into main Jul 5, 2022
@Baccata Baccata deleted the dfrancoeur/swagger2 branch July 5, 2022 12:38
@@ -520,32 +520,6 @@ lazy val `http4s-swagger` = projectMatrix
)
.http4sJvmPlatform(allJvmScalaVersions, jvmDimSettings)

lazy val `doc-check` = projectMatrix
Copy link
Contributor Author

@daddykotex daddykotex Jul 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh crap, I forgot to remove my test module loll

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no worries :)

@daddykotex
Copy link
Contributor Author

Ahhh, two interesting things:

  • it was my first time using the partially applied pattern, seen before, but never implemented it. I found it weird to have F[_] on apply rather that as a class type parameter. I see that you've replaced the former with the later, that's great
  • did not think about moving the blocker as case class member instead of a parameter to the apply method. again, good to see you did that

thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants