Closed yusukebe closed 1 year ago
Looks great! I like the API.
Some thoughts I’ve had wile working with my “type-knit” project that might be relevant here as well:
const postRoute = api .post( '/posts', validator((v) => ({ id: v.json('id'), title: v.json('title'), })), (c) => { const post = c.req.valid() return DoClient(dostub).json(“/increment”, {title: post.title}) } ) .build() ‘’’
Looks great! Is the client a wrapper of the web native fetch?
@Talent30
Yes, I'm planning to wrap fetch
though the client has not been designed yet.
@yusukebe Thank you for your response! Have you thought about how it would handle multipart/form-data?
@yusukebe Thank you for your response! Have you thought about how it would handle multipart/form-data?
You are thinking about file upload? I think each client method is a specific spec. For example client.json() is a POST request with content-type application/json. Similarly there could be a client.upload() that uses multi-part though I’m not sure that’s need for a first release to keep things simple.
@Talent30 @cleaton
Of course I am thinking about that. I think we can implement c.form()
or the more generic c.post()
.
BTW,
At the moment, I am working on an API design for "client". I am looking into other libraries and trying to create the "client" prototypes.
This has almost nothing to do with Hono, but I also created this interesting client.
https://github.com/yusukebe/xc
I think it is a pretty good idea to be able to specify such headers and queries in the callback.
const json = await client
.get('/shops/:shopId', (c) => {
c.header('User-Agent', 'Xc')
c.param('shopId', 'yoshimuraya')
}).json()
It's just an idea. I need to consider it more.
Also, and this is still undecided too, I am thinking of deprecating the built-in Validator and doing Validation with such "Zod". I really like the Built-in Validator, but implementing the Validator on my own is a difficult thing to do. It also complicates the code.
For example, I'm trying the following implementations.
const postRoute = app
.post(
'/post',
zValidator(
'json',
z.object({
title: z.string(),
body: z.string(),
})
),
async (c) => {
const { title, body } = c.req.valid()
c.jsonT({ message: `${title} : ${body}` })
}
)
.build()
const authorRoute = app
.post(
'/author',
zValidator(
'form',
z.object({
name: z.string(),
age: z.number(),
})
),
async (c) => {
const { name, age } = c.req.valid()
c.jsonT({ message: `${name} : ${age}` })
}
)
.build()
type AppType = typeof postRoute & typeof authorRoute
Pretty good, right?
This will be a separate Issue.
There are still many decisions that need to be made. However, I would like to take my time.
const json = await client .get('/shops/:shopId', (c) => { c.header('User-Agent', 'Xc') c.param('shopId', 'yoshimuraya') }).json()
It's just an idea. I need to consider it more.
I am working on similar experiments. Instead of callback with context thought to make the client api argument always be of type {headers: Record<string,string>, params: Record<string,string>, body: T} .
Yes, this approach is also good.
{headers: Record<string,string>, params: Record<string,string>, body: T}
This is the current status:
https://user-images.githubusercontent.com/10682/209410398-0bc8f62f-67ad-4699-8d49-8f66a2ad77ee.mov
zod-validator
as middleware.hono/client
.These are just ideas!
If we create zod-validator
, I am wondering if we should make it a built-in middleware or @hono/zod-validator
as a 3rd-party. This is because the policy is that built-in middleware should not depend on external libraries.
But this Validator is important. It might be better to make it a built-in middleware. It is also easier to maintain. So, how about do not include it in dependencies, but install zod
when the developer want to use it. If so, we have to specify it in the peerDependencies
section.
@yusukebe the demo looks amazing, good job. Personally i think the zod validator should be separate. Better keep the core without specific 3rd party validators and instead only expose a validator Interface ex (unknown) => T. For example if you use this API to create RPC access to internal durable objects it might be enough to only have compile time type errors for clients and no actual runtime validations (worker - DO connection is trusted). Zod can be too heavy for some cases.
Created the PR related to this issue: https://github.com/honojs/hono/pull/745
This looks great, but I think the client API could be slightly improved. Like with Eden the routes could be called using a chained method call.
So /api/users/getUser
could be called via client.api.users.getUser()
. I think this API is more robust than using a string.
Also I agree with @cleaton about keeping the zod validation seperate.
This is the current status:
https://user-images.githubusercontent.com/10682/210257864-58f05fdb-fb67-4d10-ade0-5686091f62dd.mov
Stack:
Love this work. Would vote heavily in favor of making zod
the default validator. It just has so much adoption and integrations throughout the TS community. Honestly, the number one thing that turned me off when first going through the hono
docs was that it used yet another custom validation library. I understand why, and I agree that you can make things generic and have a zod-validator
; just keep in mind that every addition of a generic option increases complexity for the end developer to understand and choose between.
Really excited about this feature as a much more lightweight alternative to trpc
, which in my experience just feels really bloated in terms of the number of different moving parts that it takes to get a basic full-stack, type-safe API up & running.
@transitive-bullshit
just keep in mind that every addition of a generic option increases complexity for the end developer to understand and choose between.
Yes. I could feel the importance of this in the development of Hono over the past year. I would like to design the API with this in mind. Thanks.
The thing that I value about trpc is it's easy integration into react/nextjs via tanstack/query. Is there a future where this could be wrapped like that to make the transition from trpc to hono easier?
Current status:
https://user-images.githubusercontent.com/10682/215533246-8dcd3e58-c834-4629-b826-03fc43fe4820.mov
I'm re-designing the client API.
@yusukebe
would it be possible to batch up requests that happen at the same time into one like TRPC ? how to test your current progress ? how would I be able to help ?
thanks.
hc
or "Hono Client" is just a very thin wrapper of fetch
. I think we can implement batch
with some ideas.
This client can perhaps be used in writing tests. Can you show an example of that, please?
Hi there.
I've created the PR for introducing "Hono Client". This was created as @hono/hc
but made obsolete and include in the core package because of DX.
https://github.com/honojs/hono/pull/862
It may be difficult to try since we haven't published it as npm yet, but you can see it in the PR comment and the tests.
@yusukebe I have a couple of questions ?
zodValidator
from, "hono/validator" does not seem to be working ?~ found out that I need to install @hono/zod-validator
hc
?Done!
hc
or "Hono Client" is just a very thin wrapper offetch
. I think we can implementbatch
with some ideas.
Sorry to open an old thread, but I could find any information about the batch in Hono client, is it possible?
Hi @robertveloso !
batch
is not implemented yet. Thanks.
I'll introduce an ultra cool feature. It will improve our developer experience. This issue is a continuation of #602.
"tRPC" is helpful for sharing the types between the server and the client. This means it makes the types an API specification. There is a request to make tRPC adapter #582 , I think it's good to make the adapter as 3rd party middleware.
So, tPRC is great, but we can do it in a better way with Hono because we can make it "integrated".
What we want to do are below:
Then, I have created those prototypes. They are not fully implemented, but they work. See the screencast:
Server-side code:
Client-side code:
The client-side needs to be considered, but this is a good idea for the server-side API. And, if developers want to use 3rd party validator like a "Zod", they may use it.
Notes, we need to brush up on our data structures to handle types with Generics.
Isn't it cool? I may create the PR later.