GithubHelp home page GithubHelp logo

Comments (14)

Wicpar avatar Wicpar commented on May 20, 2024

The project has evolved and the documentation and examples haven't.
It would be nice to have some help writing the wiki, i have trouble structuring it into relevant/less relevant information for beginners.

Exception handling is not yet completely fleshed out, but got improved in 0.2-experimental:

throws(HttpStatusCode.BadRequest, CustomException::class) { ... // no example, just the exception handling
throws(HttpStatusCode.BadRequest, "example", CustomException::class) { ... // exception  handling with example, will respond example
throws(HttpStatusCode.BadRequest, "example", {ex: CustomException -> ex.toString()}) { ... // exception handling, will respond generated content

The usage would be clearer like this:

exception<TheExceptionToCatch, ReturnTypeToSerialize>(
HttpStatusCode.BadRequest // the response status code
) {
    it.printStackTrace() // do stuff like print stacktrace
    ReturnTypeToSerialize(it)  // return any type you want to respond (strings generally)
}

Status codes are hard coded per handler because OpenAPI needs to know statically what it needs to be, without the endpoint being called.

For the routes:

    get<ParameterType, ResponseType> { params ->       // get request on '/' because no path is specified
        respond(ResponseType(...))
    }

    route("someroute").get<ParameterType, ResponseType>(   //  get request on '/someroute'
        info("String Param Endpoint", "This is a String Param Endpoint"), // A Route module that describes an endpoint, it is optional
        example = ResponseType(...) // example for the OpenAPI data
    ) { params ->
        respond(ResponseType(...))
    }

routes can be written in a chained manner:

route("a").route("b")...

or

route("a") {
    route("b") {
        ...
    }
}

both are strictly the same and generate handlers that will prepend "/a/b" to get or post handlers.

Is this clearer ?

from ktor-openapi-generator.

uuf6429 avatar uuf6429 commented on May 20, 2024

Is this clearer ?

Yes, very much. Would be nice to have these sort of examples. If I manage to get some time, I'll try contributing as well.

from ktor-openapi-generator.

JavierPAYTEF avatar JavierPAYTEF commented on May 20, 2024

Hi, to add a little to the other request, it would be nice to have a full example project, with all the verbs used.
I couldn't find examples using "post", or simple things like "get" example that doesn't receive any parameters but returns something.

One thing to mention is that the code appears to have no comments, so I have trouble understanding what I need to put in some of the parameters.

For example, if I see the following piece of code I don't know what is P, or R, I also don't know what I can put in RouteOpenAPIModule apart from info.
I'm switching between navigating the source in github and trying to guess what goes where based on the few examples.
If I had a comment saying "R is the request type, if you don't have input parameters set it to blah" or "@param modules You can use [info] here to add descriptions" it would be super useful.

@ContextDsl
inline fun <reified P : Any, reified R : Any> NormalOpenAPIRoute.get(
    vararg modules: RouteOpenAPIModule,
    example: R? = null,
    crossinline body: suspend OpenAPIPipelineResponseContext<R>.(P) -> Unit
) = route(HttpMethod.Get, modules, example, body)

from ktor-openapi-generator.

Wicpar avatar Wicpar commented on May 20, 2024

I agree, If you do a pull request with documentation comments i'll accept it.
It might take while until this is worked on on my side if not.

from ktor-openapi-generator.

uuf6429 avatar uuf6429 commented on May 20, 2024

To be fair, I think that using P, T etc is a bad practice coming from Kotlin. Most Kotlin generic functionality does this.
It would have been nice to adopt a standard such as TSomething's, eg, TRequest, TParams or:

public fun <TValue> listOf(vararg elements: TValue): List<TValue> =
     ...

from ktor-openapi-generator.

JavierPAYTEF avatar JavierPAYTEF commented on May 20, 2024

It would definitely help to have those generics have a better name like TParams, TRequest, TResponse.

In the Kotlin example you sent "elements" kind of explains what T is, so we can give it pass, since it would be redundant to have "elements: TElement".

But, for the example I sent, your idea is good because no parameter explains what R or P are, the only names in the method are "modules", "example" and "body", and none of those are "response" or "parameters" (I assume the P is for Parameters?).
So better names would make it more understandable for sure without extensive documentation.

@Wicpar I can try to add some comments and improve the names if you are open to it. Maybe I should start with the classes more likely to be used by users. Which packages do you think would be good to start on?

from ktor-openapi-generator.

Wicpar avatar Wicpar commented on May 20, 2024

Yes, TSomething is a way better pattern than the first letter capitalised, i'll start using it.

@JavierPAYTEF the best package to start on is com.papsign.ktor.openapigen.route.path

from ktor-openapi-generator.

JavierPAYTEF avatar JavierPAYTEF commented on May 20, 2024

Hey I'm currently writting the docs and changing the names but I'm going crazy with a problem I can't find the reason for. The body and response for all my services are empty.
I managed to track it to RequestHandlerModule when it does provider.ofType<BodyParser>() it always returns null.
I'm not sure why the BodyParser module is empty. Do I need to register the BodyParser myself someway?

This is an example of the data clases not appearing:

data class PinPadStatusReq(
    var language: String = "es", // es
    var pinpad: String = "*" // *
)

data class PinPadStatusResp(
    var datacenterMessage: String = "Conexión estable",
    var datacenterPingMS: Int = 140,
    var pinpads: List<Pinpad> = listOf(Pinpad())
) {
    data class Pinpad(
        var default: Boolean = true,
        var serialNumber: String = "123456789",
        var status: String = "#connected"
    )
}

This is my configuration:

val api = install(OpenAPIGen) {
	oaConfig.installIn(this)
}
install(ContentNegotiation) {
	/*jackson {
		setSerializationInclusion(JsonInclude.Include.NON_NULL)
		enable(SerializationFeature.INDENT_OUTPUT) // Pretty Prints the JSON
	}*/
	jackson {
		enable(
			DeserializationFeature.WRAP_EXCEPTIONS,
			DeserializationFeature.USE_BIG_INTEGER_FOR_INTS,
			DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS
		)

		enable(SerializationFeature.WRAP_EXCEPTIONS, SerializationFeature.INDENT_OUTPUT)

		setSerializationInclusion(JsonInclude.Include.NON_NULL)

		setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
			indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
			indentObjectsWith(DefaultIndenter("  ", "\n"))
		})

		//registerModule(JavaTimeModule())
	}
}
install(CallLogging) {
	level = Level.DEBUG
}
install(StatusPages) {
	withAPI(api) {
		exception<Exception, ErrorResponse>(HttpStatusCode.InternalServerError) { exception ->
			ResponseBuilder.error(exception)
		}
		status(HttpStatusCode.NotFound) {
			call.respond(
				HttpStatusCode.NotFound,
				ResponseBuilder.error("notFound", "Requested page was not found")
			)
		}
	}
}
routing{
	get("/openapi.json") {
		call.respond(application.openAPIGen.api.serialize())
	}
	get("/swagger") {
		call.respondRedirect("/swagger-ui/index.html?url=/openapi.json", true)
	}
}
apiRouting {
	route("/pinpad/status") {
		post<Unit, PinPadStatusResp, PinPadStatusReq>(
			info("PIN/PAD status"),
			exampleResponse = PinPadStatusResp(),
			exampleRequest = PinPadStatusReq()
		) { _, body ->
			respond(PinPadStatusResp())
		}
	}
}

This is what the json looks like:

json

from ktor-openapi-generator.

JavierPAYTEF avatar JavierPAYTEF commented on May 20, 2024

I made it work somehow, but had to change part of the configuration, I'm guessing this is not done because I'm compiling in Android and it's not detecting something. If I do the following it works:

val api = install(OpenAPIGen) {
	// ... the default config here ...
	addModules(
		DefaultCollectionSchemaProvider,
		DefaultEnumSchemaProvider,
		DefaultMapSchemaProvider,
		DefaultObjectSchemaProvider,
		DefaultPrimitiveSchemaProvider,
		DefaultSetSchemaProvider,
		NothingSchemaProvider
	)
}
FinalSchemaBuilderProvider.onInit(api)
KtorContentProvider.onInit(api)

from ktor-openapi-generator.

Wicpar avatar Wicpar commented on May 20, 2024

@JavierPAYTEF sorry for the late response.
The library uses reflections to detect the default modules. I didn't think to test with Android if this worked. It seems that it doesn't.

from ktor-openapi-generator.

JavierPAYTEF avatar JavierPAYTEF commented on May 20, 2024

Hi @Wicpar I created a pull request that adds a couple of the changes we talked about in here.
Please let me know if I'm on the right track, you might want to edit some of the texts, please let me know.
The pull request shouldn't have any functional changes compared to the current version, it should only be name changes and comments.

from ktor-openapi-generator.

mattrussell-sonocent avatar mattrussell-sonocent commented on May 20, 2024

I couldn't find examples using "post", or simple things like "get" example that doesn't receive any parameters but returns something.

This may not be the right place to ask, but how do you do a get that doesn't take any parameters?

from ktor-openapi-generator.

Wicpar avatar Wicpar commented on May 20, 2024

You can useUnit

from ktor-openapi-generator.

mattrussell-sonocent avatar mattrussell-sonocent commented on May 20, 2024

You can useUnit

👍 Thanks

from ktor-openapi-generator.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.