-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathcompositor.json
138 lines (138 loc) · 16.5 KB
/
compositor.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
{
"name": "cdimascio/swagger-spring-functional",
"version": "0.1.4",
"libraries": {
"xv": "^1.1.25"
},
"title": "",
"branch": "",
"style": {
"name": "Default",
"componentSet": {
"nav": "nav/BasicNav",
"header": "header/BannerHeader",
"article": "article/BasicArticle",
"footer": "footer/BasicFooter"
},
"fontFamily": "-apple-system, BlinkMacSystemFont, sans-serif",
"fontWeight": 400,
"bold": 600,
"lineHeight": 1.5,
"typeScale": [
72,
48,
24,
20,
16,
14,
12
],
"monospace": "Menlo, monospace",
"heading": {
"fontFamily": null,
"fontStyle": null,
"fontWeight": 600,
"lineHeight": 1.25,
"textTransform": null,
"letterSpacing": null
},
"h0": {},
"h1": {},
"h2": {},
"h3": {},
"h4": {},
"h5": {},
"h6": {},
"alternativeText": {},
"space": [
0,
8,
16,
32,
48,
64,
96
],
"layout": {
"maxWidth": 1024,
"centered": false
},
"colors": {
"text": "#111",
"background": "#fff",
"primary": "#08e",
"secondary": "#059",
"highlight": "#e08",
"border": "#ddd",
"muted": "#eee"
},
"border": {
"width": 1,
"radius": 2
},
"link": {},
"button": {
"hover": {
"boxShadow": "inset 0 0 0 999px rgba(0, 0, 0, .125)"
}
},
"input": {},
"body": {
"margin": 0
},
"breakpoints": {
"xs": "@media screen and (max-width:40em)",
"sm": "@media screen and (min-width:40em)",
"md": "@media screen and (min-width:52em)",
"lg": "@media screen and (min-width:64em)"
}
},
"content": [
{
"component": "nav",
"links": [
{
"href": "https://github.com/cdimascio/swagger-spring-functional",
"text": "GitHub"
}
]
},
{
"component": "header",
"heading": "swagger-spring-functional",
"subhead": "A friendly kotlin library used to validate API endpoints against a Swagger 2.0 specification",
"children": [
{
"component": "ui/TweetButton",
"text": "swagger-spring-functional: A friendly kotlin library used to validate API endpoints against a Swagger 2.0 specification",
"url": ""
},
{
"component": "ui/GithubButton",
"user": "cdimascio",
"repo": "swagger-spring-functional"
}
]
},
{
"component": "article",
"metadata": {
"source": "github.readme"
},
"html": "\n<p><img src=\"https://travis-ci.org/cdimascio/openapi-spring-webflux-validator.svg?branch=master\"><a href=\"https://www.codacy.com/app/cdimascio/openapi-spring-webflux-validator?utm_source=github.com&utm_medium=referral&utm_content=cdimascio/openapi-spring-webflux-validator&utm_campaign=Badge_Grade\"><img src=\"https://api.codacy.com/project/badge/Grade/f78b72ca90104e42b111723a7720adf3\"></a><img src=\"https://img.shields.io/badge/license-Apache%202.0-blue.svg\"></p>\n<p>A friendly kotlin library to validate API endpoints using an <em>OpenApi 3.0.0</em> or <em>Swagger 2.0</em> specification. Great with webflux functional. \nIt <strong>works happily with any JVM language including Java >=8</strong>. </p>\n<p>\n <img src=\"https://raw.githubusercontent.com/cdimascio/openapi-spring-webflux-validator/master/assets/openapi-spring5-webflux-validator.png\">\n</p>\n\n<p>Supports specifications in <em>YAML</em> and <em>JSON</em></p>\n<p>See this <a href=\"https://github.com/cdimascio/kotlin-swagger-spring-functional-template\">complete Spring 5 Webflux example that uses openapi-spring-webflux-validator</a>.</p>\n<h2>Prequisites</h2>\n<p>Java 8 or greater</p>\n<h2>Install</h2>\n<h3>Maven</h3>\n<pre><span class=\"hljs-tag\"><<span class=\"hljs-name\">dependency</span>></span>\n <span class=\"hljs-tag\"><<span class=\"hljs-name\">groupId</span>></span>io.github.cdimascio<span class=\"hljs-tag\"></<span class=\"hljs-name\">groupId</span>></span>\n <span class=\"hljs-tag\"><<span class=\"hljs-name\">artifactId</span>></span>openapi-spring-webflux-validator<span class=\"hljs-tag\"></<span class=\"hljs-name\">artifactId</span>></span>\n <span class=\"hljs-tag\"><<span class=\"hljs-name\">version</span>></span>2.0.0<span class=\"hljs-tag\"></<span class=\"hljs-name\">version</span>></span>\n<span class=\"hljs-tag\"></<span class=\"hljs-name\">dependency</span>></span></pre><h3>Gradle</h3>\n<pre>compile <span class=\"hljs-string\">'io.github.cdimascio:openapi-spring-webflux-validator:2.0.0'</span></pre><p>For sbt, grape, ivy and more, see <a href=\"https://search.maven.org/#artifactdetails%7Cio.github.cdimascio%7Copenapi-spring-webflux-validator%7C2.0.0%7Cjar\">here</a></p>\n<h2>Usage (Kotlin)</h2>\n<p>This section and the next describe usage with Kotlin and Java respectively.</p>\n<h3>Configure (Kotlin)</h3>\n<p>This one-time configuration requires you to provide the <em>location of the openapi/swagger specification</em> and an optional <em>custom error handler</em>.</p>\n<p>Supports <code>JSON</code> and <code>YAML</code></p>\n<pre><span class=\"hljs-keyword\">import</span> io.github.cdimascio.swagger.Validate\n<span class=\"hljs-keyword\">val</span> validate = Validate.configure(<span class=\"hljs-string\">"static/api.yaml"</span>)</pre><p>with custom error handler</p>\n<pre><span class=\"hljs-keyword\">data</span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyError</span></span>(<span class=\"hljs-keyword\">val</span> id: String, <span class=\"hljs-keyword\">val</span> messages: List<String>)\n<span class=\"hljs-keyword\">val</span> validate = Validate.configure(<span class=\"hljs-string\">"static/api.json"</span>) { status, messages ->\n Error(status.name, messages)\n}</pre><p>with custom ObjectMapper factory:</p>\n<pre><span class=\"hljs-keyword\">val</span> validate = Validate.configure(\n openApiSwaggerPath = <span class=\"hljs-string\">"api.yaml"</span>,\n errorHandler = { status, message -> ValidationError(status.value(), message[<span class=\"hljs-number\">0</span>]) },\n objectMapperFactory = { ObjectMapper()\n .registerKotlinModule()\n .registerModule(JavaTimeModule())\n .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, <span class=\"hljs-literal\">false</span>) }\n)</pre><h3>Validate a request (Kotlin)</h3>\n<p>Using the <code>validate</code> instance created above, you can now validate a request:</p>\n<p>without a body</p>\n<pre>validate.request(req) {\n <span class=\"hljs-comment\">// Do stuff e.g. return a list of names </span>\n ok().body(Mono.just(listOf(<span class=\"hljs-string\">"carmine"</span>, <span class=\"hljs-string\">"alex"</span>, <span class=\"hljs-string\">"eliana"</span>)))\n}</pre><p>with body</p>\n<pre>validate.request(req).withBody(User::<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span>.<span class=\"hljs-title\">java</span>) </span>{ body ->\n <span class=\"hljs-comment\">// Note that body is deserialized as User!</span>\n <span class=\"hljs-comment\">// Now you can do stuff. </span>\n <span class=\"hljs-comment\">// For example, lets echo the request as the response </span>\n ok().body(Mono.just(body))\n}</pre><h2>Usage (Java 8 <em>or greater</em>)</h2>\n<h3>Configure (Java)</h3>\n<p>This one-time configuration requires you to provide the <em>location of the openapi/swagger specification</em> and an optional <em>custom error handler</em>.</p>\n<pre><span class=\"hljs-keyword\">import</span> io.github.cdimascio.swagger.Validate;\nValidate<ValidationError> validate = Validate.configure(<span class=\"hljs-string\">"static/api.json"</span>)</pre><p>with custom error handler</p>\n<pre><span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyError</span> </span>{\n <span class=\"hljs-keyword\">private</span> String id;\n <span class=\"hljs-keyword\">private</span> String messages;\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-title\">MyError</span><span class=\"hljs-params\">(String id, List<String> messages)</span> </span>{\n <span class=\"hljs-keyword\">this</span>.id = id;\n <span class=\"hljs-keyword\">this</span>.messages = messages;\n }\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> String <span class=\"hljs-title\">getId</span><span class=\"hljs-params\">()</span> </span>{\n <span class=\"hljs-keyword\">return</span> id;\n }\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">setId</span><span class=\"hljs-params\">(String id)</span> </span>{\n <span class=\"hljs-keyword\">this</span>.id = id;\n }\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> List<String> <span class=\"hljs-title\">getMessages</span><span class=\"hljs-params\">()</span> </span>{\n <span class=\"hljs-keyword\">return</span> messages;\n }\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <span class=\"hljs-keyword\">void</span> <span class=\"hljs-title\">setMessages</span><span class=\"hljs-params\">(List<String> messages)</span> </span>{\n <span class=\"hljs-keyword\">this</span>.messages = messages;\n } \n}</pre><pre>Validate<ValidationError> validate = Validate.configure(<span class=\"hljs-string\">"static/api.json"</span>, (status, messages) ->\n <span class=\"hljs-keyword\">new</span> MyError(status.getName(), messages)\n);</pre><h3>Validate a request (Java)</h3>\n<p>Using the <code>validate</code> instance created above, you can now validate a request:</p>\n<p>without a body</p>\n<pre>ArrayList<String> users = <span class=\"hljs-keyword\">new</span> ArrayList<String>() {{\n add(<span class=\"hljs-string\">"carmine"</span>);\n add(<span class=\"hljs-string\">"alex"</span>);\n add(<span class=\"hljs-string\">"eliana"</span>);\n}};\n\nvalidate.request(<span class=\"hljs-keyword\">null</span>, () -> {\n <span class=\"hljs-comment\">// Do stuff e.g. return a list of user names</span>\n ServerResponse.ok().body(fromObject(users));\n});</pre><p>with body</p>\n<pre>validate\n .request(<span class=\"hljs-keyword\">null</span>)\n .withBody(User.class, user -> \n <span class=\"hljs-comment\">// Note that body is deserialized as User!</span>\n <span class=\"hljs-comment\">// Now you can do stuff. </span>\n <span class=\"hljs-comment\">// For example, lets echo the request as the response</span>\n <span class=\"hljs-keyword\">return</span> ServerResponse.ok().body(fromObject(user))\n );</pre><h2>Example Valiation Output</h2>\n<p>Let's assume a <code>POST</code> request to create a user requires the following request body:</p>\n<pre>{\n <span class=\"hljs-attr\">"firstname"</span>: <span class=\"hljs-string\">"carmine"</span>,\n <span class=\"hljs-attr\">"lastname"</span>: <span class=\"hljs-string\">"dimasico"</span>\n}</pre><p>Let's now assume an API user misspells <code>lastname</code> as <code>lastnam</code></p>\n<pre>curl -X POST http://localhost:8080/api/users -H "Content-Type: application/json" -d'{ \n "firstname": "c", \n "lastnam": "d" \n}'</pre><p><code>openapi-spring-webflux-validator</code> automatically validates the request against a Swagger spect and returns:</p>\n<pre>{\n <span class=\"hljs-attr\">"code"</span>: <span class=\"hljs-number\">400</span>,\n <span class=\"hljs-attr\">"messages"</span>:[\n <span class=\"hljs-string\">"Object instance has properties which are not allowed by the schema: [\\"lastnam\\"]"</span>,\n <span class=\"hljs-string\">"Object has missing required properties ([\\"lastname\\"])"</span>\n ]\n}</pre><p><strong>Woah! Cool!!</strong> :-D </p>\n<h2>Example</h2>\n<p>Let's say you have an endpoint <code>/users</code> that supports both <code>GET</code> and <code>POST</code> operations.</p>\n<p>You can create those routes and validate them like so:</p>\n<p><strong>Create the routes:</strong></p>\n<pre><span class=\"hljs-keyword\">package</span> myproject.controllers\n\n<span class=\"hljs-keyword\">import</span> org.springframework.core.io.ClassPathResource\n<span class=\"hljs-keyword\">import</span> org.springframework.http.MediaType.*\n<span class=\"hljs-keyword\">import</span> org.springframework.web.reactive.function.server.ServerResponse.permanentRedirect\n<span class=\"hljs-keyword\">import</span> org.springframework.web.reactive.function.server.router\n<span class=\"hljs-keyword\">import</span> java.net.URI\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">Routes</span></span>(<span class=\"hljs-keyword\">private</span> <span class=\"hljs-keyword\">val</span> userHandler: UserHandler) {\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">fun</span> <span class=\"hljs-title\">router</span><span class=\"hljs-params\">()</span></span> = router {\n <span class=\"hljs-string\">"/api"</span>.nest {\n accept(APPLICATION_JSON).nest {\n POST(<span class=\"hljs-string\">"/users"</span>, userHandler::create)\n }\n accept(TEXT_EVENT_STREAM).nest {\n GET(<span class=\"hljs-string\">"/users"</span>, userHandler::findAll)\n }\n }\n }\n}</pre><pre><span class=\"hljs-keyword\">package</span> myproject\n\n<span class=\"hljs-keyword\">import</span> io.github.cdimascio.swagger.Validate\n<span class=\"hljs-keyword\">val</span> validate = Validate.configure(<span class=\"hljs-string\">"static/api.yaml"</span>)</pre><p><strong>Validate with openapi-spring-webflux-validator</strong></p>\n<pre><span class=\"hljs-keyword\">package</span> myproject.controllers\n\n<span class=\"hljs-keyword\">import</span> myproject.models.User\n<span class=\"hljs-keyword\">import</span> myproject.validate\n<span class=\"hljs-keyword\">import</span> org.springframework.web.reactive.function.server.ServerRequest\n<span class=\"hljs-keyword\">import</span> org.springframework.web.reactive.function.server.ServerResponse\n<span class=\"hljs-keyword\">import</span> org.springframework.web.reactive.function.server.ServerResponse.ok\n<span class=\"hljs-keyword\">import</span> org.springframework.web.reactive.function.server.body\n<span class=\"hljs-keyword\">import</span> reactor.core.publisher.Flux\n<span class=\"hljs-keyword\">import</span> reactor.core.publisher.Mono\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">UserHandler</span> </span>{\n\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">fun</span> <span class=\"hljs-title\">findAll</span><span class=\"hljs-params\">(req: <span class=\"hljs-type\">ServerRequest</span>)</span></span>: Mono<ServerResponse> {\n <span class=\"hljs-keyword\">return</span> validate.request(req) {\n ok().body(Mono.just(listOf(<span class=\"hljs-string\">"carmine"</span>, <span class=\"hljs-string\">"alex"</span>, <span class=\"hljs-string\">"eliana"</span>)))\n }\n }\n\n <span class=\"hljs-function\"><span class=\"hljs-keyword\">fun</span> <span class=\"hljs-title\">create</span><span class=\"hljs-params\">(req: <span class=\"hljs-type\">ServerRequest</span>)</span></span>: Mono<ServerResponse> {\n <span class=\"hljs-keyword\">return</span> validate.request(req).withBody(User::<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span>.<span class=\"hljs-title\">java</span>) </span>{\n <span class=\"hljs-comment\">// it is the request body deserialized as User</span>\n ok().body(Mono.just(it))\n }\n }\n}</pre><h2>License</h2>\n<p><a href=\"https://www.apache.org/licenses/LICENSE-2.0\">Apache 2.0</a></p>\n"
},
{
"component": "footer",
"links": [
{
"href": "https://github.com/cdimascio/swagger-spring-functional",
"text": "GitHub"
},
{
"href": "https://github.com/cdimascio",
"text": "cdimascio"
}
]
}
]
}