11package org .saurabh .users ;
22
3+ import com .fasterxml .jackson .databind .node .TextNode ;
34import io .javalin .Javalin ;
45import io .javalin .config .JavalinConfig ;
6+ import io .javalin .openapi .JsonSchemaLoader ;
57import io .javalin .openapi .plugin .OpenApiPlugin ;
6- import io .javalin .openapi .plugin .OpenApiPluginConfiguration ;
7- import io .javalin .openapi .plugin .redoc .ReDocConfiguration ;
88import io .javalin .openapi .plugin .redoc .ReDocPlugin ;
9- import io .javalin .openapi .plugin .swagger .SwaggerConfiguration ;
109import io .javalin .openapi .plugin .swagger .SwaggerPlugin ;
10+ import io .javalin .security .RouteRole ;
1111import org .slf4j .Logger ;
1212import org .slf4j .LoggerFactory ;
1313
1818import static io .javalin .apibuilder .ApiBuilder .patch ;
1919import static io .javalin .apibuilder .ApiBuilder .path ;
2020import static io .javalin .apibuilder .ApiBuilder .post ;
21+ import static org .saurabh .users .JavalinOpenApiExampleApp .Rules .ANONYMOUS ;
2122
2223public class JavalinOpenApiExampleApp {
2324
25+ enum Rules implements RouteRole {
26+ ANONYMOUS ,
27+ USER ,
28+ }
29+
2430 private static final Logger LOG = LoggerFactory .getLogger (JavalinOpenApiExampleApp .class );
2531 public final Javalin app ;
2632
@@ -35,30 +41,95 @@ public static void main(String[] args) {
3541 }
3642
3743 private static Javalin javalinApp () {
38- return Javalin .create (openapiConfigConsumer ())
39- .routes (() -> {
40- path (
41- "users" ,
42- () -> {
43- get (UserController ::getAll );
44- post (UserController ::create );
45- path ("{userId}" , () -> {
46- get (UserController ::getOne );
47- patch (UserController ::update );
48- delete (UserController ::delete );
49- });
44+ return Javalin .create (javalinConfig -> {
45+
46+ openapiConfigConsumer ();
47+
48+ for (var generatedJsonSchema : new JsonSchemaLoader ().loadGeneratedSchemes ()) {
49+ System .out .println (generatedJsonSchema .getName ());
50+ System .out .println (generatedJsonSchema .getContentAsString ());
51+ }
52+
53+ javalinConfig .router .apiBuilder (() -> {
54+ path (
55+ "users" ,
56+ () -> {
57+ get (UserController ::getAll );
58+ post (UserController ::create );
59+ path ("{userId}" , () -> {
60+ get (UserController ::getOne );
61+ patch (UserController ::update );
62+ delete (UserController ::delete );
5063 });
51- get ("/ui" , ctx -> ctx .html ("<h1>User UI</h1>" ));
52- }
53- );
64+ });
65+ get ("/ui" , ctx -> ctx .html ("<h1>User UI</h1>" ));
66+ });
67+ });
5468 }
5569
5670 private static Consumer <JavalinConfig > openapiConfigConsumer () {
5771 return config -> {
58- final var openApiConfiguration = new OpenApiPluginConfiguration ();
59- config .plugins .register (new OpenApiPlugin (openApiConfiguration ));
60- config .plugins .register (new SwaggerPlugin (new SwaggerConfiguration ()));
61- config .plugins .register (new ReDocPlugin (new ReDocConfiguration ()));
72+ // config.routing.contextPath = "/custom";
73+ final var deprecatedDocsPath = "/api/openapi.json" ; // by default it's /openapi
74+
75+ config .registerPlugin (new OpenApiPlugin (openApiConfig ->
76+ openApiConfig
77+ .withDocumentationPath (deprecatedDocsPath )
78+ .withRoles (ANONYMOUS )
79+ .withDefinitionConfiguration ((version , openApiDefinition ) ->
80+ openApiDefinition
81+ .withInfo (openApiInfo ->
82+ openApiInfo
83+ .description ("App description goes right here" )
84+ .termsOfService ("https://example.com/tos" )
85+ .
contact (
"API Support" ,
"https://www.example.com/support" ,
"[email protected] " )
86+ .license ("Apache 2.0" , "https://www.apache.org/licenses/" , "Apache-2.0" )
87+ )
88+ .withServer (openApiServer ->
89+ openApiServer
90+ .description ("Server description goes here" )
91+ .url ("http://localhost:{port}{basePath}/" + version + "/" )
92+ .variable ("port" , "Server's port" , "8080" , "8080" , "7070" )
93+ .variable ("basePath" , "Base path of the server" , "" , "" , "v1" )
94+ )
95+ // Based on official example: https://swagger.io/docs/specification/authentication/oauth2/
96+ .withSecurity (openApiSecurity ->
97+ openApiSecurity
98+ .withBasicAuth ()
99+ .withBearerAuth ()
100+ .withApiKeyAuth ("ApiKeyAuth" , "X-Api-Key" )
101+ .withCookieAuth ("CookieAuth" , "JSESSIONID" )
102+ .withOpenID ("OpenID" , "https://example.com/.well-known/openid-configuration" )
103+ .withOAuth2 (
104+ "OAuth2" ,
105+ "This API uses OAuth 2 with the implicit grant flow." ,
106+ oauth2 ->
107+ oauth2
108+ .withClientCredentials ("https://api.example.com/credentials/authorize" )
109+ .withImplicitFlow ("https://api.example.com/oauth2/authorize" , flow ->
110+ flow
111+ .withScope ("read_pets" , "read your pets" )
112+ .withScope ("write_pets" , "modify pets in your account" )
113+ )
114+ )
115+ .withGlobalSecurity ("OAuth2" , globalSecurity ->
116+ globalSecurity
117+ .withScope ("write_pets" )
118+ .withScope ("read_pets" )
119+ )
120+ )
121+ .withDefinitionProcessor (content -> { // you can add whatever you want to this document using your favourite json api
122+ content .set ("test" , new TextNode ("Value" ));
123+ return content .toPrettyString ();
124+ })
125+ )));
126+ config .registerPlugin (new SwaggerPlugin (swaggerConfiguration -> {
127+ swaggerConfiguration .setDocumentationPath (deprecatedDocsPath );
128+ }));
129+
130+ config .registerPlugin (new ReDocPlugin (reDocConfiguration -> {
131+ reDocConfiguration .setDocumentationPath (deprecatedDocsPath );
132+ }));
62133 };
63134 }
64135
0 commit comments