https://kotlinlang.org logo
#http4k
Title
# http4k
d

dave

02/23/2018, 3:05 PM
Copy code
fun add(value1: Int, value2: Int): HttpHandler = {
        Response(OK).with(
            Body.string(TEXT_PLAIN).toLens() of (value1 + value2).toString()
        )}

    val contract = contract(OpenApi(ApiInfo("my great api", "v1.0"), Argo),
        "/add" / <http://Path.int|Path.int>().of("value1") / Path.fixed("hello") / <http://Path.int|Path.int>().of("value2") meta {
            summary = "add"
            description = "Adds 2 numbers together"
            returning("The result" to OK)
        } bindContract GET
            to { a, _, c -> add(a, c) }
    )

    contract.asServer(Jetty(8000)).start()
e

elifarley

02/23/2018, 4:39 PM
In this example, how can I see the generated API documentation ?
d

dave

02/23/2018, 4:41 PM
The docs default to the root
e

elifarley

02/23/2018, 4:46 PM
so it should be at http://localhost:8000/ ?
I've tested both and they don't work. I mean, I've tested on my own setup, which is a bit different:
val productsRoute: RouteBinder<(String, String) -> HttpHandler> = "/catalogs" / Path.string().of("catalog-name", "Catalog name ('Client-Realm-Id' in headers)") / Path.fixed("products") meta { summary = "Get products from a catalog given a catalog name" } bindContract GET val sgzrHandler: RoutingHttpHandler = routes( "/sgzr/api/v1" bind contract(OpenApi(ApiInfo("Stargazer-O API", "v1.0"), Argo), "Manages product sales", security, echoRoute to ::echo, productsRoute to { a, _ -> getProducts(a) } ) )
d

dave

02/23/2018, 5:06 PM
it should be at the root of the contract, which in your case is
/sgzr/api/v1
e

elifarley

02/23/2018, 5:08 PM
Ok, I'll focus my tests on the root of the contract
RESPONSE 404 to GET: /sgzr/api/v1/
However:
RESPONSE 200 to GET: /sgzr/api/v1/catalogs/x/products
d

dave

02/23/2018, 5:15 PM
Hnm - can you try overriding the path of the description route?
(in the contract method)
@elifarley got it - the problem is that you've passed in a description where the path to the description route should be.
e

elifarley

02/23/2018, 5:35 PM
hmmm
d

dave

02/23/2018, 5:36 PM
Copy code
val productsRoute: RouteBinder<(String, String) -> HttpHandler> =
        "/catalogs" / Path.string().of("catalog-name", "Catalog name ('Client-Realm-Id' in  headers)") /
            Path.fixed("products") meta {
            summary = "Get products from a catalog given a catalog name"
        } bindContract GET

    val sgzrHandler: RoutingHttpHandler = routes(
        "/sgzr/api/v1" bind contract(OpenApi(ApiInfo("Stargazer-O API", "v1.0"), Argo), "", NoSecurity,
            productsRoute to { a, _ -> { Response(OK) } }
        )
    )

    sgzrHandler.asServer(Jetty(8000)).start()
e

elifarley

02/23/2018, 5:36 PM
I see. Should I create a PR to change the argument name from description to descriptionPath ?
Or it's better not to change it?
d

dave

02/23/2018, 5:38 PM
weird - which version are you on? that argument should already be called descriptionPath. Here's the source:
Copy code
fun contract(renderer: ContractRenderer = NoRenderer, descriptionPath: String = "", security: Security = NoSecurity, vararg serverRoutes: ContractRoute) =
    ContractRoutingHttpHandler(renderer, security, descriptionPath, "", serverRoutes.map { it })
e

elifarley

02/23/2018, 5:38 PM
Duh! My bad!!! It's already properly named descriptionPath !!!
thanks again 🙂
I guess I just did it too hastily
d

dave

02/23/2018, 5:39 PM
no problem. This is the problem with Strings - they're just not very descriptive! We don't have a type for "path segment", so it ended up being a string 🙂
e

elifarley

02/23/2018, 6:17 PM
I see...
2 Views