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

chore(server): rewrite resolveHTTPResponse with Fetch #5684

Merged
merged 115 commits into from Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
d5eb98b
Revert "fix: rollback formdata/octet type stream support (#5661)"
Nick-Lucas Apr 23, 2024
a19547d
add regression test
KATT Apr 21, 2024
d3e65c0
cool
KATT Apr 21, 2024
38ebbdf
Add concurrentCache to safely store promises for the body
Nick-Lucas Apr 22, 2024
55ee77f
Add cache straight to adapter
Nick-Lucas Apr 22, 2024
93749da
Add doc comment
Nick-Lucas Apr 22, 2024
dbe9428
Remove reundant code
Nick-Lucas Apr 22, 2024
270b354
Add tests for other adapters
Nick-Lucas Apr 22, 2024
c1c2abd
Simply impl
Nick-Lucas Apr 22, 2024
fd9ecc7
Fix linting
Nick-Lucas Apr 23, 2024
af57d9d
Fix express test
Nick-Lucas Apr 23, 2024
662baa8
Do next-prisma-starter
Nick-Lucas Apr 21, 2024
78a8a63
Bump typescript eslint parser to support ts 5.4.2
Nick-Lucas Apr 21, 2024
2568a57
chore: apply lint and formatting fixes
autofix-ci[bot] Apr 21, 2024
42a4b49
regenerate lock file
Nick-Lucas Apr 23, 2024
564c5fa
Fix test types
Nick-Lucas Apr 24, 2024
fb7e9a1
wip
KATT Apr 26, 2024
cfd3d2b
add memo fn
KATT Apr 24, 2024
cb6b609
mkay
KATT Apr 26, 2024
3bd4afc
simplify
KATT Apr 26, 2024
d95a527
cool
KATT Apr 26, 2024
d928f17
cool
KATT Apr 26, 2024
76c9ee7
wip
KATT Apr 26, 2024
ae446d7
wip
KATT Apr 26, 2024
69c5c43
some fix
KATT Apr 26, 2024
d78071c
wip
KATT Apr 26, 2024
80fbdd5
fix some
KATT Apr 26, 2024
73c8f4b
method override
KATT Apr 26, 2024
32d0f5a
locky
KATT Apr 26, 2024
9da6e69
cool
KATT Apr 26, 2024
0b3e09e
fix
KATT Apr 26, 2024
c676a67
wat
KATT Apr 26, 2024
0cd8a2d
formData
KATT Apr 26, 2024
3ff7bf4
fix formdata
KATT Apr 26, 2024
0fa724d
cool
KATT Apr 21, 2024
d765e9d
add regression test
KATT Apr 21, 2024
5a7e82d
cool
KATT Apr 26, 2024
b041b53
a security fix aye
KATT Apr 26, 2024
ec0e087
chore: apply lint and formatting fixes
autofix-ci[bot] Apr 26, 2024
739de29
fix stuff
KATT Apr 26, 2024
003850d
Merge branch '04-26-resolveResponse' of github.com:trpc/trpc into 04-…
KATT Apr 26, 2024
a091d1b
no `.only()`
KATT Apr 26, 2024
d368390
tweak
KATT Apr 26, 2024
6f7ca36
Upgrade vitest
Nick-Lucas Apr 26, 2024
5f3f9c9
fix test
KATT Apr 26, 2024
631e948
TextEncoderStream
Sheraff Apr 26, 2024
cf12fa6
ugly but w/e
KATT Apr 26, 2024
35c7cc1
Merge branch '04-26-resolveResponse' of github.com:trpc/trpc into 04-…
KATT Apr 26, 2024
895d845
chore: apply lint and formatting fixes
autofix-ci[bot] Apr 26, 2024
acaeb36
Fix the bug
Nick-Lucas Apr 26, 2024
6e01f07
Merge branch 'next' of github.com:trpc/trpc into issues/5659-multi-bo…
Nick-Lucas Apr 26, 2024
87e86fc
chore: apply lint and formatting fixes
autofix-ci[bot] Apr 26, 2024
167bc20
add more tests
KATT Apr 27, 2024
805bc74
Merge branch '04-26-resolveResponse' of github.com:trpc/trpc into 04-…
KATT Apr 27, 2024
31479c5
payload too large
KATT Apr 27, 2024
624f6c6
tweak
KATT Apr 27, 2024
12c618a
release
KATT Apr 27, 2024
19b54d8
Merge remote-tracking branch 'origin/next' into issues/5659-multi-bod…
KATT Apr 27, 2024
9b02d70
tmp release
KATT Apr 27, 2024
68f7b52
fix test
KATT Apr 27, 2024
b86279a
Merge branch 'issues/5659-multi-body-read' into 04-26-resolveResponse…
KATT Apr 27, 2024
1389e65
wip
KATT Apr 27, 2024
b267fbc
colocate
KATT Apr 28, 2024
f4b3b80
simplify
KATT Apr 28, 2024
f62bc66
add some tests
KATT Apr 28, 2024
5c99bc7
next
KATT Apr 28, 2024
5dabae3
fix
KATT Apr 28, 2024
cf91b5b
cool
KATT Apr 28, 2024
3a4c8ff
hi
KATT Apr 28, 2024
764407c
mk
KATT Apr 28, 2024
4242604
fixes
KATT Apr 28, 2024
9586408
rm
KATT Apr 28, 2024
9eb99ea
release
KATT Apr 28, 2024
23f42bf
fix
KATT Apr 28, 2024
5bcf80d
fix
KATT Apr 28, 2024
6e35200
fix
KATT Apr 28, 2024
3d3cac7
rel
KATT Apr 28, 2024
66509c6
cool
KATT Apr 28, 2024
496fc8f
cool
KATT Apr 28, 2024
eaf88e6
cool
KATT Apr 28, 2024
073e93b
chore: move more stuff to fetch api (#5685)
KATT Apr 28, 2024
7521c05
mv parseOctetInput to http
KATT Apr 28, 2024
257bf55
revert some tests that work now
KATT Apr 28, 2024
84b43d2
tweak
KATT Apr 28, 2024
3bb3659
tweak
KATT Apr 28, 2024
1dcdc61
cool
KATT Apr 28, 2024
b11c387
sort
KATT Apr 28, 2024
f9b794d
chore: apply lint and formatting fixes
autofix-ci[bot] Apr 28, 2024
be4bf90
04 26 resolve response and multi align example (#5686)
KATT Apr 28, 2024
e67ee92
04 26 resolve response and multi happy ts (#5687)
KATT Apr 28, 2024
2f00300
cool
KATT Apr 28, 2024
ffb40b1
Merge branch '04-26-resolveResponse-and-multi' of github.com:trpc/trp…
KATT Apr 28, 2024
3095a21
cool
KATT Apr 28, 2024
e3feaae
Merge branch 'next' into issues/5659-multi-body-read
KATT Apr 28, 2024
d4fb197
Merge branch 'issues/5659-multi-body-read' into 04-26-resolveResponse…
KATT Apr 28, 2024
1d98672
Merge branch 'next' into issues/5659-multi-body-read
KATT Apr 28, 2024
22d05ab
Merge branch 'issues/5659-multi-body-read' into 04-26-resolveResponse…
KATT Apr 28, 2024
67ca904
fix
KATT Apr 28, 2024
3e85ff8
rewrite lambda adapter (#5690)
KATT Apr 28, 2024
fb53a74
Merge branch 'next' into issues/5659-multi-body-read
KATT Apr 28, 2024
033dc62
Merge branch 'issues/5659-multi-body-read' into 04-26-resolveResponse…
KATT Apr 28, 2024
33cf415
parts
KATT Apr 29, 2024
328bcc4
tweak
KATT Apr 29, 2024
ed9d992
cool
KATT Apr 29, 2024
c1585b6
tweak
KATT Apr 30, 2024
699d7d0
Revert "tweak"
KATT Apr 30, 2024
3d33679
chore: move complexity from `resolveResponse` (#5691)
KATT Apr 30, 2024
7edfea7
Merge remote-tracking branch 'origin/next' into 04-26-resolveResponse…
KATT Apr 30, 2024
d52febe
Revert "Merge remote-tracking branch 'origin/next' into 04-26-resolve…
KATT Apr 30, 2024
2462a0e
more readable diff
KATT Apr 30, 2024
5ff0e7e
mkay
KATT Apr 30, 2024
26da399
fix
KATT Apr 30, 2024
b321139
tweak
KATT Apr 30, 2024
d207027
fix
KATT Apr 30, 2024
2c13b76
decode
KATT Apr 30, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Expand Up @@ -76,7 +76,6 @@ jobs:
dir:
[
.experimental/next-app-dir,
.experimental/next-formdata,
.test/diagnostics-big-router,
.test/internal-types-export,
.test/ssg,
Expand All @@ -85,6 +84,7 @@ jobs:
express-server,
fastify-server,
minimal-react,
next-formdata,
next-minimal-starter,
next-prisma-starter,
next-prisma-todomvc,
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release-tmp.yml
Expand Up @@ -4,9 +4,9 @@ on:
push:
branches:
# Replace this with the branch you want to release from
# 👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
- 'issues/5659-multi-body-read'
# 👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆
# 👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
- '04-26-resolveResponse-and-multi'
# 👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆
paths:
- '.github/workflows/release-tmp.yml'
- 'packages/**'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/subtree.yml
Expand Up @@ -22,7 +22,7 @@ jobs:
next-big-router,
minimal,
minimal-react,
.experimental/next-formdata,
next-formdata,
.experimental/next-app-dir,
]

Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Expand Up @@ -82,11 +82,11 @@ The most complex types are also in this area because we must keep track of the c

#### Handling a Request and Forming a Response

The core implementation for HTTP handling is contained in [`resolveHTTPResponse`](packages/server/src/http/resolveHTTPResponse.ts) where requests are handled and an object representing a response is created. This function deals with handling different methods (`query` and `mutation` have different specs), batching, streaming, etc. so it is an excellent place to get an overview of the complete process of handling a request and forming a response. If you want to learn more about the specification that we implement, read [this docs page](https://trpc.io/docs/rpc).
The core implementation for HTTP handling is contained in [`resolveResponse`](packages/server/src/http/resolveHTTPResponse.ts) where [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)s are handled and a [`Response`-object](https://developer.mozilla.org/en-US/docs/Web/API/Response) is created. This function deals with handling different methods (`query` and `mutation` have different specs), batching, streaming, etc. so it is an excellent place to get an overview of the complete process of handling a request and forming a response. If you want to learn more about the specification that we implement, read [this docs page](https://trpc.io/docs/rpc).

#### Adapting Requests and Responses

Adapters are what connect our framework-agnostic HTTP handling into a server response. We offer official adapters for some popular frameworks, although adapters can also be third-party. Adapters "adapt" their framework's request object into a common format and the object response from `resolveHTTPResponse` into their framework-specific responses. This keeps tRPC framework-agnostic, an important principle that allows it to be used in any environment.
Adapters are what connect our framework-agnostic HTTP handling into a server response. We offer official adapters for some popular frameworks, although adapters can also be third-party. Adapters "adapt" their framework's request object into a common format and the object response from `resolveResponse` into their framework-specific responses. This keeps tRPC framework-agnostic, an important principle that allows it to be used in any environment.

### `@trpc/client`

Expand Down
28 changes: 0 additions & 28 deletions examples/.experimental/next-formdata/README.md

This file was deleted.

Expand Up @@ -6,12 +6,19 @@ export function SendMultipartFormDataButton() {
return (
<button
onClick={() => {
const data = new FormData();
const fd = new FormData();

data.set('name', 'John Doe');
data.set('occupation', 'tRPC Extraordinaire');
fd.set('name', 'John Doe');
fd.set('occupation', 'tRPC Extraordinaire');

mutation.mutate(data);
fd.set(
'about',
new File(['hi bob'], 'bob.txt', {
type: 'text/plain',
}),
);
Comment on lines +14 to +19
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @Nick-Lucas

I don't see why you'd want to use octet streams over FormData?

If you upload a file you can just do this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saying this because it seems a lot easier to deal with a File than a ReadableStream

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choice is good, not everything is a File and you might also want to stream a file direct to some storage which I don't believe FormData could do, it would have to fit in memory (or have hi-jinks like we used to have)


mutation.mutate(fd);
}}
>
Send FormData
Expand Down
77 changes: 39 additions & 38 deletions examples/minimal-content-types/server/index.ts
Expand Up @@ -2,62 +2,63 @@
* This is the API-handler of your app that contains all your API routes.
* On a bigger app, you will probably want to split this file up into multiple files.
*/
import { initTRPC, parseOctetInput } from '@trpc/server';
import { initTRPC } from '@trpc/server';
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import { octetInputParser } from '@trpc/server/http';
import cors from 'cors';
import type { z } from 'zod';
import { z } from 'zod';

const t = initTRPC.create();

const publicProcedure = t.procedure;
const router = t.router;

// A fake type parser which just expects the appropriate type to be passed through
function asType<TOut, TIn = unknown>(): z.ZodType<TOut, any, TIn> {
return {
parse: (input: unknown) => {
console.log('parser received', input);
return input as TOut;
},
} as z.ZodType<TOut, any, TIn>;
}

const appRouter = router({
// Input parsers set! (should expect the input to be loaded into memory)
formData: publicProcedure.input(asType<FormData>()).mutation(({ input }) => {
const object = {} as Record<string, unknown>;
input.forEach((value, key) => (object[key] = value));

console.log('FormData: ', object, input);

return {
text: 'ACK',
data: object,
};
}),
file: publicProcedure
.input(parseOctetInput<File>())
formData: publicProcedure
.input(z.instanceof(FormData))
.mutation(async ({ input }) => {
const chunks = [];

const reader = input.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
const object = {} as Record<string, unknown>;
for (const [key, value] of input.entries()) {
if (value instanceof File) {
object[key] = {
name: value.name,
type: value.type,
size: value.size,
text: await value.text(),
};
} else {
object[key] = value;
}
chunks.push(value);
}

const content = Buffer.concat(chunks).toString('utf-8');

console.log('File: ', content);
console.log('FormData: ', object);

return {
text: 'ACK',
data: content,
data: object,
};
}),
file: publicProcedure.input(octetInputParser).mutation(async ({ input }) => {
const chunks = [];

const reader = input.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
chunks.push(value);
}

const content = Buffer.concat(chunks).toString('utf-8');

console.log('File: ', content);

return {
text: 'ACK',
data: content,
};
}),
});

// export only the type definition of the API
Expand Down
1 change: 1 addition & 0 deletions examples/minimal-content-types/server/tsconfig.json
Expand Up @@ -2,6 +2,7 @@
"compilerOptions": {
"moduleResolution": "node",
"esModuleInterop": true,
"target": "ESNext",
"strict": true,
"outDir": "dist"
}
Expand Down
12 changes: 12 additions & 0 deletions examples/next-formdata/README.md
@@ -0,0 +1,12 @@
# Next.js + tRPC + `FormData`

This example showcases how to use tRPC with `FormData`.

## Setup

```bash
npx create-next-app --example https://github.com/trpc/trpc --example-path examples/next-formdata trpc-formdata
cd trpc-formdata
npm i
npm run dev
```
12 changes: 1 addition & 11 deletions packages/server/package.json
Expand Up @@ -58,16 +58,6 @@
"require": "./dist/adapters/next.js",
"default": "./dist/adapters/next.js"
},
"./adapters/node-http/content-type/form-data": {
"import": "./dist/adapters/node-http/content-type/form-data/index.mjs",
"require": "./dist/adapters/node-http/content-type/form-data/index.js",
"default": "./dist/adapters/node-http/content-type/form-data/index.js"
},
"./adapters/node-http/content-type/json": {
"import": "./dist/adapters/node-http/content-type/json/index.mjs",
"require": "./dist/adapters/node-http/content-type/json/index.js",
"default": "./dist/adapters/node-http/content-type/json/index.js"
},
"./adapters/node-http": {
"import": "./dist/adapters/node-http/index.mjs",
"require": "./dist/adapters/node-http/index.js",
Expand Down Expand Up @@ -128,7 +118,7 @@
"devDependencies": {
"@fastify/websocket": "^10.0.1",
"@tanstack/react-query": "^5.25.0",
"@types/aws-lambda": "^8.10.97",
"@types/aws-lambda": "^8.10.137",
"@types/express": "^4.17.17",
"@types/hash-sum": "^1.0.0",
"@types/node": "^20.10.0",
Expand Down
2 changes: 0 additions & 2 deletions packages/server/rollup.config.ts
Expand Up @@ -9,8 +9,6 @@ export const input = [
'src/adapters/fetch/index.ts',
'src/adapters/next-app-dir.ts',
'src/adapters/next.ts',
'src/adapters/node-http/content-type/form-data/index.ts',
'src/adapters/node-http/content-type/json/index.ts',
'src/adapters/node-http/index.ts',
'src/adapters/standalone.ts',
'src/adapters/ws.ts',
Expand Down
19 changes: 7 additions & 12 deletions packages/server/src/@trpc/server/http.ts
@@ -1,26 +1,21 @@
export {
getHTTPStatusCode,
getHTTPStatusCodeFromError,
resolveResponse,
} from '../../unstable-core-do-not-import';
export { resolveHTTPResponse } from '../../unstable-core-do-not-import';
export type {
BaseHandlerOptions,
HTTPBaseHandlerOptions,
HTTPHeaders,
HTTPRequest,
HTTPResponse,
OnErrorFunction,
ProcedureCall,
HTTPErrorHandler,
/**
* @deprecated Use `HTTPErrorHandler` instead
*/
HTTPErrorHandler as OnErrorFunction,
ResolveHTTPRequestOptionsContextFn,
ResponseChunk,
ResponseMeta,
ResponseMetaFn,
TRPCRequestInfo,
} from '../../unstable-core-do-not-import';

export { getBatchStreamFormatter } from '../../unstable-core-do-not-import';
export type {
BaseContentTypeHandler,
BodyResult,
} from '../../unstable-core-do-not-import';
export { toURL } from '../../unstable-core-do-not-import';
export { octetInputParser, toURL } from '../../unstable-core-do-not-import';
3 changes: 0 additions & 3 deletions packages/server/src/@trpc/server/index.ts
Expand Up @@ -33,7 +33,6 @@ export {
type AnySubscriptionProcedure as AnyTRPCSubscriptionProcedure,
type ProcedureOptions as TRPCProcedureOptions,
type CreateContextCallback,
type WrapCreateContext,
type MutationProcedure as TRPCMutationProcedure,
type QueryProcedure as TRPCQueryProcedure,
type SubscriptionProcedure as TRPCSubscriptionProcedure,
Expand Down Expand Up @@ -104,5 +103,3 @@ export {
*/
export type inferAsyncReturnType<TFunction extends (...args: any[]) => any> =
Awaited<ReturnType<TFunction>>;

export { parseOctetInput } from '../../unstable-core-do-not-import/contentTypeParsers';