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

flatten post requests' input #671

Merged
merged 4 commits into from Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/client/src/internals/httpRequest.ts
Expand Up @@ -39,9 +39,8 @@ export function httpRequest<TResponseShape = TRPCResponse>(props: {
if (type === 'query') {
return undefined;
}
return JSON.stringify({
input: rt.transformer.serialize(input),
});
const rawInput = rt.transformer.serialize(input);
return rawInput !== undefined ? JSON.stringify(rawInput) : undefined;
}

const promise = new Promise<TResponseShape>((resolve, reject) => {
Expand Down
4 changes: 4 additions & 0 deletions packages/server/src/http/internals/getPostBody.ts
Expand Up @@ -23,6 +23,10 @@ export async function getPostBody({
});
req.on('end', () => {
try {
if (body === '') {
resolve(undefined);
return;
}
const json = JSON.parse(body);
resolve(json);
} catch (err) {
Expand Down
16 changes: 14 additions & 2 deletions packages/server/src/http/requestHandler.ts
Expand Up @@ -54,9 +54,21 @@ async function getRequestParams({
return { input };
}

const { input } = await getPostBody({ req, maxBodySize });
const body = await getPostBody({ req, maxBodySize });
/**
* @deprecated TODO delete me for next major
* */
if (
body &&
typeof body === 'object' &&
'input' in body &&
Object.keys(body).length === 1
) {
// legacy format
return { input: body.input };
}

return { input };
return { input: body };
}

export async function requestHandler<
Expand Down
1 change: 1 addition & 0 deletions packages/server/test/_testHelpers.ts
Expand Up @@ -85,6 +85,7 @@ export function routerToServerAndClient<TRouter extends AnyRouter>(
port: httpPort,
httpPort,
wssPort,
httpUrl,
applyWSSHandlerOpts,
wssHandler,
wss,
Expand Down
42 changes: 42 additions & 0 deletions packages/server/test/rawFetch.test.tsx
@@ -0,0 +1,42 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/ban-types */
import { z } from 'zod';
import * as trpc from '../src';
import { routerToServerAndClient } from './_testHelpers';
import fetch from 'node-fetch';
test('call mutation with `input`-prop', async () => {
const { close, httpUrl } = routerToServerAndClient(
trpc.router().mutation('myMutation', {
input: z.object({
name: z.string(),
}),
async resolve({ input }) {
return { input };
},
}),
);

const res = await fetch(`${httpUrl}/myMutation`, {
method: 'POST',
body: JSON.stringify({
input: {
name: 'alexdotjs',
},
}),
});
const json = await res.json();

expect(json.result).toMatchInlineSnapshot(`
Object {
"data": Object {
"input": Object {
"name": "alexdotjs",
},
},
"type": "data",
}
`);

close();
});
10 changes: 5 additions & 5 deletions www/docs/further/further-reading.md
Expand Up @@ -36,8 +36,8 @@ tRPC is a lot simpler and couples your server & website/app more tightly togethe

### HTTP Methods <-> Type mapping

| HTTP Method | Mapping | Notes |
| -------------------- | ----------------- | ------------------------------------------------------------------------------------------------------ |
| `GET` | `.query()` | Input JSON-stringified in query param.<br/>_e.g._ `?input=${JSON.stringify(encodeURIComponent(input))` |
| `POST` | `.mutation()` | Input in post body. |
| `PATCH` / WebSockets | `.subscription()` | Input in post body.<br/>:warning: Experimental. API might change without major version bump. |
| HTTP Method | Mapping | Notes |
| ----------- | ----------------- | ------------------------------------------------------------------------------------------------------ |
| `GET` | `.query()` | Input JSON-stringified in query param.<br/>_e.g._ `?input=${JSON.stringify(encodeURIComponent(input))` |
| `POST` | `.mutation()` | Input as post body. |
| WebSockets | `.subscription()` | Input as post body.<br/>:warning: Experimental. API might change without major version bump. |