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

Path parameters are not percent-encoded by Hono client #3933

Open
kylemclean opened this issue Feb 18, 2025 · 1 comment
Open

Path parameters are not percent-encoded by Hono client #3933

kylemclean opened this issue Feb 18, 2025 · 1 comment
Labels

Comments

@kylemclean
Copy link

kylemclean commented Feb 18, 2025

What version of Hono are you using?

4.7.1

What runtime/platform is your app running on? (with version if possible)

Node.js

What steps can reproduce the bug?

Description

When making a request using the Hono client to a route with a path parameter, parameter values are not percent-encoded, resulting in incorrect URLs being requested if any of the path parameter values contain certain characters.

Steps to reproduce

  1. Create a new Hono project.

  2. Add the following Hono server implementation.

index.ts

import { serve } from "@hono/node-server";
import { Hono } from "hono";

const app = new Hono().get("/:x", (c) => {
  const params = c.req.param();
  return c.json(params);
});

export type AppType = typeof app;

serve({ fetch: app.fetch, port: 3000 });
  1. Add the following Hono client implementation.

client.ts

import { hc } from "hono/client";
import type { AppType } from "./index.js";

const client = hc<AppType>("http://localhost:3000");

client[":x"]
  .$get({ param: { x: "test/value" } })
  .then((response) => response.json())
  .then(console.log);
  1. Run the server by executing the command npm run dev

  2. Run the client by executing the command npx tsx src/client.ts

What is the expected behavior?

The client should call the /:x route on the server, passing the string value "test/value" as the :x path parameter. It would do this by percent-encoding all of the path parameters before adding them to the URL, resulting in a request being made to the path /test%2Fvalue.

This should result in the response {"x": "test/value"} being received and logged on the client.

What do you see instead?

The client instead makes a request to /test/value, which does not resolve to the /:x route and thus results in a 404 error.

Additional information

As a workaround, you can call encodeURIComponent on path parameter values, and the parameter values are automatically decoded on the server.

client[":x"]
  .$get({ param: { x: encodeURIComponent("test/value") } });

I think that doing this automatically in Hono would solve the issue, though this would break user code that already does this. Perhaps the param option can be deprecated and a new option params or pathParams can be introduced that automatically percent-encodes its values.

@yusukebe
Copy link
Member

@kylemclean

First, the path /:x can't handle /test/value with not only Hono Client. The following code will output 404. This is expected behavior.

const app = new Hono().get('/:x', (c) => {
  const params = c.req.param()
  return c.json(params)
})

const res = await app.request('/test/value')
console.log(res.status) // 404

If you want to handle /test/value, you should write the following:

const app = new Hono().get('/:x{.+}', (c) => {
//...
})

Second, the Hono Client adds the just path string with param. So it should not encode the value of param. The following works correctly. There is no problem.

import { hc } from 'hono/client'
import type { AppType } from './index'

const client = hc<AppType>('http://localhost:3000')

const url = client[':x'].$url({
  param: {
    x: 'test/value',
  },
})

console.log(url.toString()) // http://localhost:3000/test/value

This is not a bug.

@yusukebe yusukebe added not bug and removed triage labels Feb 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants