Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

415 unsupported media type when using mount to add routes #3500

Closed
mgeorge opened this issue Aug 12, 2024 · 8 comments · Fixed by #3502
Closed

415 unsupported media type when using mount to add routes #3500

mgeorge opened this issue Aug 12, 2024 · 8 comments · Fixed by #3502
Milestone

Comments

@mgeorge
Copy link

mgeorge commented Aug 12, 2024

This is a weird one that started happening since 3.0.8 onwards.

If I add a POST route that is declared in another router via a mount then I get a 415 error when POSTing a valid JSON payload.

If I add the same route directly to the server, I get the expected valid response.

Best demonstrated via the following MWE:

import io.jooby.Jooby;
import io.jooby.StatusCode;
import io.jooby.gson.GsonModule;

public class WidgetService extends Jooby {

	public WidgetService() {
		install(new GsonModule());

		post("/api/widgets1", ctx -> {
			Widget widget = ctx.body().to(Widget.class);
			System.out.println("Created " + widget);
			return ctx.send(StatusCode.CREATED);
		});

		mount(new WidgetRouter());

	}

	public static void main(String[] args) {
		new WidgetService().start();
	}

}

class WidgetRouter extends Jooby {

	public WidgetRouter() {

		post("/api/widgets2", ctx -> {
			Widget widget = ctx.body().to(Widget.class);
			System.out.println("Created " + widget);
			return ctx.send(StatusCode.CREATED);
		});

	}
}

Widget is just a POJO with a couple of string fields.

A POST containing valid JSON to /api/widgets1 works and returns the expected 201 response.

The same POST to /api/widgets2 throws a 415 unsupported media type with the following stack trace:

ERROR WidgetService - POST /api/widgets2 415 Unsupported Media Type
 io.jooby.exception.UnsupportedMediaType: application/json
	at io.jooby.MessageDecoder.lambda$static$0(MessageDecoder.java:24)
	at io.jooby.DefaultContext.decode(DefaultContext.java:420)
	at io.jooby.internal.netty.NettyBody.to(NettyBody.java:103)
	at io.jooby.Body.to(Body.java:100)
	at WidgetRouter.lambda$new$baa66101$1(WidgetService.java:32)
	at io.jooby.internal.handler.DefaultHandler.lambda$apply$e67b40fd$1(DefaultHandler.java:21)
	at io.jooby.Route$Filter$1.apply(Route.java:94)
	at io.jooby.internal.handler.WorkerHandler.lambda$apply$0(WorkerHandler.java:22)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:1583)

I'm using the following dependencies in my build.gradle:

dependencies {
	def joobyVer = '3.2.7';
	implementation group: 'io.jooby', name: 'jooby-netty', version: joobyVer;
	implementation group: 'io.jooby', name: 'jooby-gson', version: joobyVer;
	implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.5.6';
}

I've been messing around with this for a bit trying to work out why my service started breaking after I upgraded from 3.0.7 to 3.2.7, and as far as I can tell, it is the use of mount to add the route that leads to the 415 error.

I've tried Jackson instead of Gson, and get the same result.

As mentioned, versions prior to 3.0.8 don't seem to have this problem.

@kliushnichenko
Copy link
Contributor

try to use install(WidgetRouter::new) instead of mount

@mgeorge
Copy link
Author

mgeorge commented Aug 13, 2024

Thanks - that did the trick.

Does that mean that mount is now deprecated? The documentation still shows it as the first option for composing routers:

https://jooby.io/#router-composing-mount

@mgeorge
Copy link
Author

mgeorge commented Aug 13, 2024

Also, sometimes you just need to call the constructor on the router in order to pass parameters. The mount method is the obvious way to do this.

@edgar-espina-wpp
Copy link
Contributor

mount should work. There is a silly difference between them: mount fetch install only routes from app, while install copy services, routes, etc...

@kliushnichenko
Copy link
Contributor

kliushnichenko commented Aug 13, 2024

if so, that #3400 was the bug as well. And a fix (or at least a part of it) is here 7370e5a, can revive the PR

@jknack
Copy link
Member

jknack commented Aug 14, 2024

@kliushnichenko first of all apologies for missing the point when you raised the bug, but yea this is the same bug as #3400. Going to send PR and you can look if I'm still missing something

@kliushnichenko
Copy link
Contributor

no worries, appreciate your support

@jknack jknack added this to the 3.2.9 milestone Aug 15, 2024
@jknack jknack closed this as completed in f414c82 Aug 15, 2024
@mgeorge
Copy link
Author

mgeorge commented Aug 22, 2024

Can confirm that this fixes my problem. Thanks for the good work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants