Skip to content

Commit fd66e0e

Browse files
authored
Update README.md
1 parent 35d7c17 commit fd66e0e

File tree

1 file changed

+9
-355
lines changed

1 file changed

+9
-355
lines changed

README.md

Lines changed: 9 additions & 355 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Extra Features:
2323

2424
It is inspired by ktor Locations, but makes no use of it.
2525

26+
## Examples
27+
2628
Take a look at [a few examples](https://github.com/papsign/Ktor-OpenAPI-Generator/wiki/A-few-examples)
2729

2830
## Installation
@@ -68,363 +70,15 @@ dependencies {
6870
}
6971
```
7072

71-
## Examples
72-
73-
Basic Example:
74-
75-
```kotlin
76-
apiRouting {
73+
## Expose the OpenAPI.json and swager-ui
7774

78-
//bare minimum, just like Ktor but strongly typed
79-
get<StringParam, StringResponse> { params ->
80-
respond(StringResponse(params.a))
81-
}
82-
83-
route("inine").get<StringParam, StringResponse>(
84-
info("String Param Endpoint", "This is a String Param Endpoint"), // A Route module that describes an endpoint, it is optional
85-
example = StringResponse("Hi")
86-
) { params ->
87-
respond(StringResponse(params.a))
88-
}
89-
90-
route("block") {
91-
// use Unit if there are no parameters / body / response
92-
post<Unit, StringUsable, StringUsable>(
93-
info("String Post Endpoint", "This is a String Post Endpoint"),
94-
exampleRequest = StringUsable("Ho"),
95-
exampleResponse = StringUsable("Ho")
96-
) { params, body ->
97-
respond(body)
98-
}
99-
}
100-
}
101-
102-
// Path works like the @Location from locations, but for transparency we recommend only using it to extract the parameters
103-
@Path("string/{a}")
104-
data class StringParam(
105-
@PathParam("A simple String Param") val a: String,
106-
@QueryParam("Optional String") val optional: String? // Nullable Types are optional
107-
)
108-
109-
// A response can be any class, but a description will be generated from the annotation
110-
@Response("A String Response")
111-
data class StringResponse(val str: String)
112-
113-
114-
// DTOs can be requests and responses, annotations are optional
115-
@Response("A String Response")
116-
@Request("A String Request")
117-
data class StringUsable(val str: String)
11875
```
119-
120-
Creates this `openapi.json` description:
121-
122-
```json
123-
{
124-
"components":{
125-
"schemas":{
126-
"StringResponse":{
127-
"nullable":false,
128-
"properties":{
129-
"str":{
130-
"nullable":false,
131-
"type":"string"
132-
}
133-
},
134-
"required":[
135-
"str"
136-
],
137-
"type":"object"
138-
},
139-
"StringUsable":{
140-
"nullable":false,
141-
"properties":{
142-
"str":{
143-
"nullable":false,
144-
"type":"string"
145-
}
146-
},
147-
"required":[
148-
"str"
149-
],
150-
"type":"object"
151-
}
152-
}
153-
},
154-
"info":{
155-
"contact":{
156-
"email":"support@test.com",
157-
"name":"Support"
158-
},
159-
"description":"The Test API",
160-
"title":"Test API",
161-
"version":"0.0.1"
162-
},
163-
"openapi":"3.0.0",
164-
"paths":{
165-
"/string/{a}":{
166-
"get":{
167-
"parameters":[
168-
{
169-
"deprecated":false,
170-
"description":"A simple String Param",
171-
"explode":false,
172-
"in":"path",
173-
"name":"a",
174-
"required":true,
175-
"schema":{
176-
"nullable":false,
177-
"type":"string"
178-
},
179-
"style":"simple"
180-
},
181-
{
182-
"allowEmptyValue":false,
183-
"deprecated":false,
184-
"description":"Optional String",
185-
"explode":false,
186-
"in":"query",
187-
"name":"optional",
188-
"required":false,
189-
"schema":{
190-
"nullable":false,
191-
"type":"string"
192-
},
193-
"style":"form"
194-
}
195-
],
196-
"responses":{
197-
"200":{
198-
"content":{
199-
"application/json":{
200-
"schema":{
201-
"$ref":"#/components/schemas/StringResponse"
202-
}
203-
}
204-
},
205-
"description":"A String Response"
206-
}
207-
}
208-
}
209-
},
210-
"/inine/string/{a}":{
211-
"get":{
212-
"description":"This is a String Param Endpoint",
213-
"parameters":[
214-
{
215-
"deprecated":false,
216-
"description":"A simple String Param",
217-
"explode":false,
218-
"in":"path",
219-
"name":"a",
220-
"required":true,
221-
"schema":{
222-
"nullable":false,
223-
"type":"string"
224-
},
225-
"style":"simple"
226-
},
227-
{
228-
"allowEmptyValue":false,
229-
"deprecated":false,
230-
"description":"Optional String",
231-
"explode":false,
232-
"in":"query",
233-
"name":"optional",
234-
"required":false,
235-
"schema":{
236-
"nullable":false,
237-
"type":"string"
238-
},
239-
"style":"form"
240-
}
241-
],
242-
"responses":{
243-
"200":{
244-
"content":{
245-
"application/json":{
246-
"example":{
247-
"str":"Hi"
248-
},
249-
"schema":{
250-
"$ref":"#/components/schemas/StringResponse"
251-
}
252-
}
253-
},
254-
"description":"A String Response"
255-
}
256-
},
257-
"summary":"String Param Endpoint"
258-
}
259-
},
260-
"/block":{
261-
"post":{
262-
"description":"This is a String Post Endpoint",
263-
"requestBody":{
264-
"content":{
265-
"application/json":{
266-
"example":{
267-
"str":"Ho"
268-
},
269-
"schema":{
270-
"$ref":"#/components/schemas/StringUsable"
271-
}
272-
}
273-
},
274-
"description":"A String Request"
275-
},
276-
"responses":{
277-
"200":{
278-
"content":{
279-
"application/json":{
280-
"example":{
281-
"str":"Ho"
282-
},
283-
"schema":{
284-
"$ref":"#/components/schemas/StringUsable"
285-
}
286-
}
287-
},
288-
"description":"A String Response"
289-
}
290-
},
291-
"summary":"String Post Endpoint"
292-
}
293-
}
294-
},
295-
"servers":[
296-
{
297-
"description":"Test server",
298-
"url":"http://localhost:8080/"
299-
}
300-
]
301-
}
302-
```
303-
304-
Full Example:
305-
306-
```kotlin
307-
import com.papsign.ktor.openapigen.OpenAPIGen
308-
import com.papsign.ktor.openapigen.annotations.Path
309-
import com.papsign.ktor.openapigen.annotations.Request
310-
import com.papsign.ktor.openapigen.annotations.Response
311-
import com.papsign.ktor.openapigen.annotations.parameters.PathParam
312-
import com.papsign.ktor.openapigen.annotations.parameters.QueryParam
313-
import com.papsign.ktor.openapigen.openAPIGen
314-
import com.papsign.ktor.openapigen.route.apiRouting
315-
import com.papsign.ktor.openapigen.route.info
316-
import com.papsign.ktor.openapigen.route.path.normal.get
317-
import com.papsign.ktor.openapigen.route.path.normal.post
318-
import com.papsign.ktor.openapigen.route.response.respond
319-
import com.papsign.ktor.openapigen.route.route
320-
import com.papsign.ktor.openapigen.schema.namer.DefaultSchemaNamer
321-
import com.papsign.ktor.openapigen.schema.namer.SchemaNamer
322-
import io.ktor.application.application
323-
import io.ktor.application.call
324-
import io.ktor.application.install
325-
import io.ktor.features.ContentNegotiation
326-
import io.ktor.jackson.jackson
327-
import io.ktor.response.respond
328-
import io.ktor.response.respondRedirect
329-
import io.ktor.routing.get
330-
import io.ktor.routing.routing
331-
import io.ktor.server.engine.embeddedServer
332-
import io.ktor.server.netty.Netty
333-
import kotlin.reflect.KType
334-
335-
object Minimal {
336-
337-
@JvmStatic
338-
fun main(args: Array<String>) {
339-
embeddedServer(Netty, 8080, "localhost") {
340-
//define basic OpenAPI info
341-
install(OpenAPIGen) {
342-
// basic info
343-
info {
344-
version = "0.0.1"
345-
title = "Test API"
346-
description = "The Test API"
347-
contact {
348-
name = "Support"
349-
email = "support@test.com"
350-
}
351-
}
352-
// describe the server, add as many as you want
353-
server("http://localhost:8080/") {
354-
description = "Test server"
355-
}
356-
//optional
357-
replaceModule(DefaultSchemaNamer, object: SchemaNamer {
358-
val regex = Regex("[A-Za-z0-9_.]+")
359-
override fun get(type: KType): String {
360-
return type.toString().replace(regex) { it.value.split(".").last() }.replace(Regex(">|<|, "), "_")
361-
}
362-
})
363-
}
364-
365-
install(ContentNegotiation) {
366-
jackson()
367-
}
368-
369-
// normal Ktor routing
370-
routing {
371-
get("/openapi.json") {
372-
call.respond(application.openAPIGen.api.serialize())
373-
}
374-
375-
get("/") {
376-
call.respondRedirect("/swagger-ui/index.html?url=/openapi.json", true)
377-
}
378-
}
379-
380-
//Described routing
381-
apiRouting {
382-
383-
//bare minimum, just like Ktor but strongly typed
384-
get<StringParam, StringResponse> { params ->
385-
respond(StringResponse(params.a))
386-
}
387-
388-
route("inine").get<StringParam, StringResponse>(
389-
info("String Param Endpoint", "This is a String Param Endpoint"), // A Route module that describes an endpoint, it is optional
390-
example = StringResponse("Hi")
391-
) { params ->
392-
respond(StringResponse(params.a))
393-
}
394-
395-
route("block") {
396-
// use Unit if there are no parameters / body / response
397-
post<Unit, StringUsable, StringUsable>(
398-
info("String Post Endpoint", "This is a String Post Endpoint"),
399-
exampleRequest = StringUsable("Ho"),
400-
exampleResponse = StringUsable("Ho")
401-
) { params, body ->
402-
respond(body)
403-
}
404-
}
405-
}
406-
}.start(true)
407-
76+
application.routing {
77+
get("/openapi.json") {
78+
call.respond(application.openAPIGen.api.serialize())
79+
}
80+
get("/") {
81+
call.respondRedirect("/swagger-ui/index.html?url=/openapi.json", true)
40882
}
409-
410-
// Path works like the @Location from locations, but for transparency we recommend only using it to extract the parameters
411-
@Path("string/{a}")
412-
data class StringParam(
413-
@PathParam("A simple String Param") val a: String,
414-
@QueryParam("Optional String") val optional: String? // Nullable Types are optional
415-
)
416-
417-
// A response can be any class, but a description will be generated from the annotation
418-
@Response("A String Response")
419-
data class StringResponse(val str: String)
420-
421-
// DTOs can be requests and responses, annotations are optional
422-
@Response("A String Response")
423-
@Request("A String Request")
424-
data class StringUsable(val str: String)
42583
}
42684
```
427-
428-
For an advanced example with most of the features, see the tests.
429-
430-

0 commit comments

Comments
 (0)