question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support for additional `Content-Type`s

See original GitHub issue

_Originally posted by @KATT in https://github.com/trpc/trpc/discussions/1936#discussioncomment-2818345_

If we go down this route what we’re really talking about is straying away from JSON as the defacto mode of transport. If we do this we should also have support for some sort of binary format when doing POSTs that could take the compression further and let us have something else than content-type: application/json.

Furthermore, I think the server should be able to receive different types of request types and be informed on what to do. I have thought about this a bit before in the context of transformers, so outlining below.

Some ideas for communicating transformers/serializer

Rough ideas below, I think best by writing code, but don’t see any of this as a final design.

contentType-param

Goals:

  • Allow for multiple content-types
  • Allow for deserializing from a Response with a body
  • Allow for serializing into a Fetch.body
  • Allow for serializing into a string for query params

When creating a server:

import { initTRPC } from '@trpc/server';
import { jsonContentType, createContentType } from '@trpc/server/content-type';

// JSON crush could be a community plugin that looks something like this:
import jsoncrush from 'jsoncrush';
const crush = createContentType({
  key: 'crush',
  contentType: 'application/json',
  // a smarter content type would use something that could be streamed, i.e ReadableStream from `Response`
  // used for `POST`:
  fromResponse: async (res) => jsoncrush.uncrush(await res.text()),
  fromString: (str) => jsoncrush.uncrush(str),
  toBody: data => jsoncrush.crush(data), // this could allow for the types that the `Fetch API` allows - ArrayBuffer, string, [...]
  // used for `GET`
  toString: data => jsoncrush.data(data),
})

const trpc = initTRPC({
  contentTypes: [
    jsonContentType,
    crush,
  }
});

HTTP level

// inform server that we are sending `crush` content
GET http://localhost?content=crush&input=[...]
GET http://localhost?content=json&input=[...]

POST http://localhost?content=crush
content-type: "application/json"
// [..]

Similarly, transformer-param could be used

import { initTRPC } from '@trpc/server';
import { defaultTransform } from '@trpc/server/transform';
// JSON crush could be a community plugin
import { crush } from 'trpc-json-crush';

const trpc = initTRPC({
  transforms: [
      defaultTransform, // our "no-op" trnasform
      { key: "superjson", value: superjson },
   ],
});

The client story

Maybe only needs to allow for one content type.

import { crush } from "~/shared/contentType"

const client = createTRPCClient({
  links: [ /* ... */ ],
  contentType: crush,
});

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:15
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
lncramercommented, Oct 6, 2022

+1 for this - I have a requirement to integrate with a webhook that expects a content type of text/xml in the response, and this is blocking me from being able to release.

Is there some other way I can currently achieve this? I’m using https://github.com/jlalmes/trpc-openapi to define the HTTP path for the webhook, but AFAICT there is no way for the associated tRPC procedure to return anything other than JSON (https://github.com/jlalmes/trpc-openapi/issues/58#issuecomment-1180631200).

EDIT: If anyone is running into the same problem, specifically with a NextJS project, I solved this by just creating a Next Response Helper to completely bypass tRPC.

This has the obvious disadvantage of losing every single benefit from tRPC, but if you’re like me and just needed a single endpoint to return a different content type then it’s an easy alternative.

3reactions
ecwynecommented, Jun 14, 2022

This would be great! I was just looking to use https://www.npmjs.com/package/notepack.io with tRPC today and came up against json being the only possible encoding

Read more comments on GitHub >

github_iconTop Results From Across the Web

Turn on support for multiple content types in a list or library
Go to the library or list for which you want to enable multiple content types. · In the SharePoint library, select the Add...
Read more >
Content-Type - HTTP - MDN Web Docs - Mozilla
The Content-Type representation header is used to indicate the original media type of the resource (prior to any content encoding applied ...
Read more >
Support for additional content types for request bodies
My understanding is that POST requests to ArcGIS REST APIs must use the form data content type to send requests.
Read more >
The contenttypes framework | Django documentation
contrib.contenttypes.models.ContentType . Instances of ContentType represent and store information about the models installed in your project, and new instances ...
Read more >
Does the HTTP Protocol support multiple content types in ...
Note that the Content-Type , as any other header, may appear twice or more. – Stephan. Nov 14, 2017 at 17:58.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found