Documenting Ktor routes with KDoc - kotlin

Does anyone know whats the correct way to document Ktor routes, aiming to show it on KDoc?
Example:
route(DogoBot.data.API.ROUTE){
route("token"){
route("add"){
get("fromdiscord") { ... }
get { ... }
}
}
route("user"){
route("{id}") {
get { ... }
}
}
route("guild"){
route("{id}") {
get { ... }
}
}
}
Well, if is it possible, how do I do this? Which type of information should I put in it? How do I implement that Ktor compatibility in other things? (I have another router made by my own for other things)

Dokka has no support for Ktor routes, and I'm not aware of any plans to add such support, so there's no way to include information about routes into the generated documentation.

Related

How to Set Kotlin Integration Test Source Directory Gradle Kotlin DSL

Please note there are several similar questions (like this and this and this and this) regarding how to set source-set for integration tests in Gradle but none of them is using JvmTestSuite.
I've got my build.gradle.kt configured as below (please let me know if full script is needed to answer my question):
testing {
suites {
val test by getting(JvmTestSuite::class) {
useJUnitJupiter()
}
val integration by registering(JvmTestSuite::class) {
testType.set(TestSuiteType.INTEGRATION_TEST)
dependencies {
implementation(project)
}
sources {
java {
setSrcDirs(listOf("src/it/java"))
}
resources {
setSrcDirs(listOf("src/it/resources"))
}
}
targets {
all {
testTask.configure {
shouldRunAfter(test)
}
}
}
}
}
}
Having that, Gradle finds my Java tests in java folder and runs them correctly. Now my question is how to set the source directory for kotlin folder. The same syntax doesn't seem to work. I also tried different solutions found on the web, but none works. Thanks.
Update
It seems to be as simple as:
java {
setSrcDirs(listOf("src/it/kotlin"))
}
I'll wait if someone else has a better answer.

Protect api routes with middleware in nextJS?

I'm new to next.js and I wanted to know if I could protect a whole API route via middleware. So for example if i wanted to protect /api/users Could I create /api/users/_middleware.ts and handle authentication in the middleware and not have to worry about authentication in the actual api endpoints? If so, how would I go about doing that? The library i'm using right now is #auth0\nextjs-auth0 so I guess it would look something like this? (Also please forgive me if I code this wrong, I am doing this in the stackoverflow editor)
export default authMiddleware(req,res)=>{
const {user,error,isLoading} = whateverTheNameOfTheAuth0HookIs()
if(user)
{
// Allow the request to the api route
}
else
{
// Deny the request with HTTP 401
}
}
Do I have the general idea correct?
next-auth v4 introduced middleware for this purpose. The basic use case is pretty simple.
You can add a middleware.js file with the following:
export { default } from "next-auth/middleware"
export const config = { matcher: ["/dashboard"] }
Other use cases can be found in the documentation
You can use middleware for that, something similar to this example from the documentation.
For a sub-directory inside pages, you can create a _middleware.ts file. It will run for all pages in this directory. It looks something like this:
import { NextRequest, NextResponse } from 'next/server'
export function middleware(req: NextRequest) {
const basicAuth = req.headers.get('authorization')
if (basicAuth) {
// do whatever checks you need here
const hasAccess = ...
if (hasAccess) {
// will render the specified page
return NextResponse.next()
}
}
// will not allow access
return new Response('No access', {
status: 401,
headers: {
'WWW-Authenticate': 'Basic realm="Secure Area"',
},
})
}
You can find more info in the documentation.

vue server side rendering and data population

Im currently refactoring an app and converting all my base code into vue. One of my requirements is to do server side rendering.
I have been follow vue ssr example along with hacker news example to help me understand ssr.
I do have however a question for which I cant find any good answer, and before further development, I want to make sure we are doing the right thing.
I want to know if its a good practice to have some actions in a vue store calling an api for server side rendering.
All the examples I have found deal with a real external endpoint they connect and perform request. But that is not the setup we have.
We do have a "normal" express app with its own endpoints; so, for example, express router looks a bit like this:
// This is our post model, it lives on the same app, so its not a external API
app.get('/posts', (req, res) => Posts.getPosts());
// Resolve request for SSR rendering, pretty much the same as in [vue ssr example](https://ssr.vuejs.org/guide/routing.html#routing-with-vue-router)
app.get(
const context = { url: req.url }
createApp(context).then(app => {
renderer.renderToString(app, (err, html) => {
if (err) {
if (err.code === 404) {
res.status(404).end('Page not found')
} else {
res.status(500).end('Internal Server Error')
}
} else {
res.end(html)
}
})
})
);
This part works fine on both client and server. If you request something to /posts you get your response back.
To have a more modular code, we are using vuex stores; being one of the actions called fetchPosts and this action is the responsible of fetching the current posts in the view.
...
actions: {
fetchPosts({ commit }) {
return $axios.get('/posts').then((response) => {
commit('setPosts', {
posts: response.data
});
});
}
},
...
I believe for client side this is good, but when rendering on the server, this is probably not optimal.
Reason being axios performing an actual http request, which will also have to implement auth mechanism, and in general, really poor performant.
My question is: is this the recommended and standard way of doing this ?
What are other possibilities that works in server and client ?
Do people actually creates separated apps for api and rendering app ?
Thanks !
I know this is an old question, but for future visitors:
The recommended way is to leverage webpack module aliases to load a server side api for the server and a client side api for the browser. You have to share the same call signature which allows the api to be "swapped".
This of course greatly improves performance as the server side api can do direct db queries instead fetching data over http.
In essence your webpack.server.config.js should have:
resolve: {
alias: {
'create-api': './create-api-server.js'
}
}
In your webpack.client.config.js:
resolve: {
alias: {
'create-api': './create-api-client.js'
}
}
Importing create-api will now load the required api.
Have a look at https://github.com/vuejs/vue-hackernews-2.0 to see a full example.

Hot to add POST interceptor to aurelia http client

Basically, the question says it all :). The scenario is as follows: I have some python models that are being passed between the browser, and the server. Python convention for naming things is to use underscores, and js convention is to camelCase everything. So I figured, I'd just create an http request interceptor to convert between python_models and jsModels. Is there a simple way to accomplish that?
I'm also looking for a way to do the inverse, so camelCase to that-case :)
If you're using aurelia-http-client, you can use a reviver.
import {HttpClient} from 'aurelia-http-client';
import {Person} from './models';
export class PersonService {
constructor(){
this.http = new HttpClient().configure(x=> {
x.withReviver((k,v) => {
return typeof v === 'object' ? new Person(v) : v;
});
});
}
getPeople(){
return this.http.get('/people');
}
}
This only works for aurelia-http-client and not aurelia-fetch-client. It has been talked about in the fetch spec, but I don't believe it is currently implemented.
Check the following for more information:
(my) Best Practices in Aurelia: The Model
https://github.com/whatwg/fetch/issues/104

Babel/ES6 extended class methods undefined

Currently I'm using Babel to write a Node.js backend in ES6. Unfortunately I encountered a strange behaviour when extending a specific class. Some of my methods, defined in the extending class, are undefined. Unless I use the ES7 syntax to bind them to a property.
This is the actual code that gives me this strange behaviour:
import { Router } from 'express';
class MyCustomRouter extends Router
{
constructor() {
super();
this.methodWorks(); // works like a charm.
this.methodDoesnt(); // throws TypeError: _this.methodDoesnt is not a function
}
methodWorks = () => {
// some content
}
methodDoesnt() {
// some content
}
}
This is actually extends the Router from the expressjs library. So right now I'm just curious if someone could explain this behaviour and/or if there is a way to fix this.
I went looking inside the code of ExpressJS itself to find some explanation. Apparently they like to return a whole new and different context from the Router's constructor. Which explains why this is totally different and not containing my methods...