varabyte / kobweb

A modern framework for full stack web apps in Kotlin, built upon Compose HTML
https://kobweb.varabyte.com
Apache License 2.0
1.53k stars 68 forks source link

Support dynamic path syntax in @Api routes #568

Closed bitspittle closed 2 months ago

bitspittle commented 3 months ago

Currently, we only support this for pages. We should also support it for API endpoints:

See also: https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/#h2-2eb87cd076da0

app.put('/articles/:id', (req, res) => {
  const { id } = req.params;
  // code to update an article...
  res.json(req.body);
});

In Kobweb, this would look like

// api/articles/Id.kt
@Api("{}")
fun id(ctx: ApiContext) {
   val id = ctx.params.getValue("id")
   // ...
}

Note that users will probably also want to support nesting this feature, so we need to support @PackageMapping as well.

From https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/#h2-8ec448c6df8c0

app.get('/articles/:articleId/comments', (req, res) => {
  const { articleId } = req.params;
  const comments = [];
  // code to get comments by articleId
  res.json(comments);
});

then in Kotlin:

// api/articles/article/PackageMapping.kt
@file:PackageMapping("{}")

package api.article

import com.varabyte.kobweb.core.PackageMapping
// api/articles/article/Comments.kt
@Api
fun comments(ctx: ApiContext) {
   val articleId = ctx.params.getValue("article")
   // ...
}

[!IMPORTANT] Dev note: Make sure that you can define both an @Api endpoint AND a package mapping both, because users will want to be able to GET both "/articles/{article}" AND "/articles/{article}/comments".

bitspittle commented 2 months ago

This will be fixed in 0.18.3 and newer.