IMVU's binary 3D content delivery format (was: Introduction)

92 views
Skip to first unread message

Chad Austin

unread,
Jun 8, 2012, 2:18:34 PM6/8/12
to 3d-...@googlegroups.com
Hi Remi,

In my introduction I forgot to share the approach we're using to deliver data to WebGL.  We want to deliver data in a format that's very easy for clients to map directly into vertex buffers, render states, etc.

The first request returns a JSON blob describing the total configuration: objects, skeletons, meshes, materials.  Each of those objects may refer to an asset URL containing textures, binary mesh data, etc.  The whole seen should require two round-trips to the network total.  First to get the total configuration and second to get all referenced assets.  Assets are quite cacheable.

Binary data is delivered in a RIFF format with two chunks: JSON and DATA.  :)  For meshes, the JSON chunk describes vertex attributes: attribute names, types, offsets into DATA chunk, strides, etc.  DATA is an otherwise-unformatted array of bytes.

Any thoughts?

On Thu, Jun 7, 2012 at 11:15 PM, Rémi Arnaud <re...@acm.org> wrote:
Welcome to the group Chad!

I have not been able to spend much time on REST-3D for a while, but I am now in a much better position and will start again spending time moving this project forward.

SigGraph is approaching soon, and I would like to get design discussion going and see if we could gather again this SigGraph in LA. How many people in this group would be interested? We could potentially set up a BOF if not too late

In the mean time, I plan to restart the discussion in the group and the work on the spec, as well as releasing some opensource software.

Regards
-Remi
-- Remi

From: Chad Austin <ch...@imvu.com>
Date: Thu, 7 Jun 2012 18:03:57 -0700 (PDT)
Subject: [3D-REST] Introduction

Hi all,

I am a technical director at IMVU, responsible for client technology.  We have an enormous catalog of user-generated content and are beginning to look into WebGL and exposing that data over a RESTful interface.  I'm joining this group to see what others in the WebGL space are doing and how we could potentially mash up our content with third-party content sources.

Nice to meet you,

Chad




--
Chad Austin
Technical Director, IMVU


Jeff Terrace

unread,
Jun 8, 2012, 3:02:06 PM6/8/12
to 3d-...@googlegroups.com
Splitting up metadata vs. binary data is definitely the way to go. One
thing I'd say is that any standard should have the binary format be
pluggable. There are a bunch of different options being used out
there. Some examples: buffers encoded in text in custom JSON formats,
buffers encoded in text in OBJ/COLLADA, an XMLHttpRequest directly
into a TypedArray, variable-length UTF-8 encoding (webgl-loader), and
OpenCTM format.

There are some tradeoffs between different approaches, so it would be
great if a server could advertise what methods it has available,
allowing a client to choose what method it wants to use for
downloading.

Jeff

Chad Austin

unread,
Jun 8, 2012, 4:16:07 PM6/8/12
to 3d-...@googlegroups.com
Thanks for the webgl-loader reference!  Looks interesting.

Regarding content negotiation, we're using the HTTP Accept header and standard client-driven content negotiation.  Given the HTTP Accept header, do you think it's still necessary for a server to advertise supported formats?

Thanks,
Chad

Rémi Arnaud

unread,
Jun 8, 2012, 5:19:44 PM6/8/12
to 3drest
I agree. Ideally the rest api would pass formatting information to the server, so it gets the data in the format best suited for its usage.
The draft spec show how do do that at high level with return of xml/json/jsonp/html for example, but should be able to retrive subsets, and ask for typed array and so forth.

-- Remi

Rémi Arnaud

unread,
Jun 8, 2012, 5:27:03 PM6/8/12
to 3drest
Personally I'd rather have this explicit in the URL, so I can use a simple wget. With any standalone app for example. http headers are lower level, not so easy to implement/debug, can be filtered out by httpd on the server before Uri redirect. In fact, Uri redirect based on query format is a nice way to implement this.

Also, will be more difficult to specify, as we would be mixing two technologies: http headers and URL. Already taking in account POST/PUT/GET methods can be confusing.


Regards
- Remi
-- Remi

From: Chad Austin <ch...@imvu.com>
Date: Fri, 8 Jun 2012 13:16:07 -0700
Subject: Re: [3D-REST] IMVU's binary 3D content delivery format (was: Introduction)

Chad Austin

unread,
Jun 8, 2012, 7:31:41 PM6/8/12
to 3d-...@googlegroups.com
We started with URLs but we found that it was annoying to pass query parameters down through the system.  For example, let's say I want to load an avatar:

GET /avatar/10

Then I have to fetch all of the textures and meshes:

GET /texture/A
GET /texture/B
GET /mesh/0
GET /mesh/1

If I'm on iOS and I want PVRTC textures instead of JPEG or PNG, I have to inform the initial request via a query parameter or some such, so that it can return me the correct texture URLs.

We found it's much nicer (and feels more like HTTP) to define MIME types for every version of the content we care about and have each client set their Accept headers appropriately.

iOS will prefer binary meshes and PVRTC textures; WebGL will prefer binary meshes and some kind of DXTC (if supported); and browsers will prefer JSON, JPEG, and PNG for human consumption.

curl makes it pretty easy from the command line to specify headers so I'm not too concerned about that.  Though we did add a query parameter to force a response content-type...  So maybe you're right and we just need the right debugging parameters.  :)

R?mi Arnaud

unread,
Jun 8, 2012, 9:37:33 PM6/8/12
to 3d-...@googlegroups.com
Interesting topic. I am not yet grasping why http headers would be better. 

Using URL to explicitly ask for a specific format still seems easier/shorter, than using http header

Compare
GET /texture/a.png

With 
    headers: {
       
'X-My-Custom-Header':'png'
;
   }
   GET /texture/A
If one want texture A in jpg, simply ask for /texture/A.jpg

What headers let you do is to ask for a set of possible formats and you get randomly one of the supported format back. I'm not sure Iike this too much as would like better control to what I get back from the server. 
 On the other hand we do need a way to discover what formats are available from the server. This could/should be one of the API calls ?

This said, I'd rather have some formats that are specified by the REST-3D specification that a server HAS to provide, this would make this API more usable/reliable.  The goal is to make it easier to write client code, and bring the conversion work on the server. 

When we will look in details how the client may request specific structure for vertex data for example, we may not be able to create a mime type for all combination we possibly want to offer. 

Regards
- Remi 

Ewen Cheslack-Postava

unread,
Jun 8, 2012, 11:29:56 PM6/8/12
to 3d-...@googlegroups.com
On 06/08/2012 06:37 PM, R?mi Arnaud wrote:
Interesting topic. I am not yet grasping why http headers would be better.
This doesn't have to be one or the other, and at least some knowledgeable people suggest it should be both: http://www.w3.org/2001/tag/doc/alternatives-discovery-20061101.html Having URLs for both the generic resource and the specific resources serve different use cases.


Using URL to explicitly ask for a specific format still seems easier/shorter, than using http header

This very much depends on what you're doing. Figuring out and holding onto a couple of headers in an application which are passed through each request automatically may be easier than constantly having to muck with URLs, or doing multiple round trips for each request in order to get to a URL for a specific format, or having to list URLs for all versions available in API responses since the client needs to select *one URL* it can get usable data from.



Compare
GET /texture/a.png

With 
    headers: {

        'X-My-Custom-Header':'png';

   }
   GET /texture/A
If one want texture A in jpg, simply ask for /texture/A.jpg

What headers let you do is to ask for a set of possible formats and you get randomly one of the supported format back. I'm not sure Iike this too much as would like better control to what I get back from the server.
 On the other hand we do need a way to discover what formats are available from the server. This could/should be one of the API calls ?

Content selection and discovery are different things. Discovery let's you figure out what formats are available and their URLs, a very important functionality if the client has some complicated reasoning in selecting what it needs, can handle different formats dynamically, needs the resource in different formats, or just wants to map what's available. This is a very good reason for having separate URLs for each individual, specific resource: you can give just a link and will be able to access the exact resource without having to add any extra headers. For the API, a separate URL that gives you that info is what I'd expect, e.g. /resourceX/formats returning JSON or XML, or something like that.

But content selection is different. It lets you specify acceptable constraints and lets the server select what it thinks is best or has available. You made it out to be unpredictable by saying you can get something random back, but that's not true. Aside from misbehaving servers, you *do* have control over what you get back -- don't include formats you don't want, and prioritize the ones you do. Of course, they may look at more than the Accept and Accept-* headers, e.g. detecting mobile browsers and sending lower resolution images.

So, coming back to the URLs vs. headers thing, content selection is why *generic* URLs are important. (Or semi-generic, you might restrict to, e.g., /modelX/collada/ but not specify other properties like level of detail, language, etc). You need the generic URLs to enable server-side content selection, picking from what it has available that you can consume. For example, this setup is nice on mobile where you want to avoid extra round trips required to do client-side selection.



This said, I'd rather have some formats that are specified by the REST-3D specification that a server HAS to provide, this would make this API more usable/reliable.  The goal is to make it easier to write client code, and bring the conversion work on the server. 

When we will look in details how the client may request specific structure for vertex data for example, we may not be able to create a mime type for all combination we possibly want to offer.

I think this is the real challenge here -- for various resource types I can think of a number of properties, some even continuous values like quality, that aren't addressed by the current headers. Quality is an obvious one. It's definitely not the right thing to do to try to encode all of that in mime types; any response type with a particular bit stream format should get a mimetype. Something like quality clearly is outside that scope.

What will really be valuable to get from this group is a *small* set of important parameters that really shape the structure of the API, and as a result, at most a couple of new X-Accept-* type headers which control them. From the API design side, I think the challenge in URL layout is to make it sane and flexible, e.g. for /resource do you support different orders for specific versions, like /resource/collada/low_quality and /resource/low_quality/collada? If not how do you handle narrowing by only the parameters you specify second? By keeping the number of dimensions you have control over to a minimum, these problems could be kept to a minimum, but they'll still need to be addressed.

-Ewen

Chad Austin

unread,
Jun 9, 2012, 12:33:37 AM6/9/12
to 3d-...@googlegroups.com
Indeed it's an interesting topic.  I still find REST somewhat challenging to wrap my head around, but there are some principles that we follow at IMVU:

- All documents should have one canonical URL.
- Clients should never construct URLs.  Documents should link to other documents.
- Documents are sort of separated from their representations.

For example, if you want information about customer 10, you would GET /customer/10

If you want the information returned as JSON, say for use in an XMLHttpRequest-based application, you send Accept: application/json.  If you want it as HTML so you can style it with CSS, you send Accept: text/html.

If asset URLs must contain content type information, then that information incorrectly propagates into links that refer to said assets.

For example, let's say I'm loading up my avatar on WebGL and a native iOS application.  The initial JSON object configuration information is the same on both platforms.  It just describes what meshes, textures, shaders, etc. go into the final object.  This information can be cached in Varnish or a CDN for all platforms.

But then, any referenced textures have a preferred representation for each platform.  When GETting textures, each client knows to set the appropriate MIME types in the Accept header.  This prevents the client from needing to construct or modify URLs and prevents format information from bleeding into referencing documents.

A simpler way to think about it is: an "object" refers to a "texture" rather than the "object" referring to a "jpeg".  The main win is that it's easy for clients to select the representation that best meets their needs.

Note that I'm not introducing a new HTTP header, I'm just reusing the standard content-negotiation system defined in HTTP 1.1.  See Accept (and Accept-Encoding) at http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Accept allows specifying priority of returning types, and you can even say "I only want image/jpeg, nothing else".

 On Fri, Jun 8, 2012 at 6:37 PM, R?mi Arnaud <re...@acm.org> wrote:
This said, I'd rather have some formats that are specified by the REST-3D specification that a server HAS to provide, this would make this API more usable/reliable.  The goal is to make it easier to write client code, and bring the conversion work on the server.

Excellent suggestion!  That's why we have a JSON format for all content types, and then optional binary formats as desired.

Thanks for the discussion!
Chad

Chad Austin

unread,
Jun 11, 2012, 4:43:51 AM6/11/12
to 3d-...@googlegroups.com
On Fri, Jun 8, 2012 at 8:29 PM, Ewen Cheslack-Postava <eche...@gmail.com> wrote:
On 06/08/2012 06:37 PM, R?mi Arnaud wrote:
Interesting topic. I am not yet grasping why http headers would be better.
This doesn't have to be one or the other, and at least some knowledgeable people suggest it should be both: http://www.w3.org/2001/tag/doc/alternatives-discovery-20061101.html Having URLs for both the generic resource and the specific resources serve different use cases.

Hi Ewen.  Thanks for the link.  There are some great arguments in there.

I'm tempted to implement 2.1.1 directly, modulo the extra 302 redirect in 2.1.1.4.  We can't afford more round-trips.  This is one of the areas where HTTP is deficient at providing a great REST interface.

This said, I'd rather have some formats that are specified by the REST-3D specification that a server HAS to provide, this would make this API more usable/reliable.  The goal is to make it easier to write client code, and bring the conversion work on the server. 

When we will look in details how the client may request specific structure for vertex data for example, we may not be able to create a mime type for all combination we possibly want to offer.
I think this is the real challenge here -- for various resource types I can think of a number of properties, some even continuous values like quality, that aren't addressed by the current headers. Quality is an obvious one. It's definitely not the right thing to do to try to encode all of that in mime types; any response type with a particular bit stream format should get a mimetype. Something like quality clearly is outside that scope.

Agreed that quality metrics aren't appropriate for MIME types.  I'd love even an unofficial standard for headers that specify maximum image sizes and the like.  Using textures as an example, if you wanted to quickly and progressively load a 3D scene, you could initially request textures with:

X-Max-Image-Size: 16

Followed by lower-priority requests with no X-Max-Image-Size.

I could imagine similar headers for mesh density and animation tolerances.

Cheers,
Chad
 

Mark Barnes

unread,
Jul 1, 2012, 5:43:01 PM7/1/12
to 3d-...@googlegroups.com
... because HTTP Content-Type header is authoritative. See RFC2616 section 7.2.1 .

Regards,
Marcus


--
Mark Barnes
Chief Scientist, Mechnicality, Inc.
http://www.mechnicality.com



On Fri, Jun 8, 2012 at 6:37 PM, R?mi Arnaud <re...@acm.org> wrote:

Rémi Arnaud

unread,
Jul 1, 2012, 5:45:43 PM7/1/12
to 3d-...@googlegroups.com
what do you mean ?

Jeff Terrace

unread,
Jul 1, 2012, 5:52:44 PM7/1/12
to 3d-...@googlegroups.com
That's important for *responses*, not really for requests.

I agree with Rémi on this one: extensive use of HTTP headers is
cumbersome for clients. It's much easier to have explicit URLs using
query parameters, rather than having to send Accept headers and then
detect what type the server sent back to you.

When I download metadata about an object, the server should give me
information about what formats the mesh and its textures are available
in, along with URLs for fetching them in the desired format. Let the
application make decisions at a higher level instead of having to mess
with HTTP headers.

Jeff

Mark Barnes

unread,
Jul 1, 2012, 5:53:37 PM7/1/12
to 3d-...@googlegroups.com
Hi Rémi,

I mean that using the http header is per-spec and using information in the URL is  "a guess" (emphasis mine) ...

Any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body. If and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection of its content and/or the name extension(s) of the URI used to identify the resource. If the media type remains unknown, the recipient SHOULD treat it as type "application/octet-stream".

m.

Mark Barnes

unread,
Jul 1, 2012, 5:55:38 PM7/1/12
to 3d-...@googlegroups.com
The spec says "any message".... I'm just asserting that any REST API based on HTTP should follow the HTTP spec... right?

m.

Jeff Terrace

unread,
Jul 1, 2012, 5:58:56 PM7/1/12
to 3d-...@googlegroups.com
No, I think you're interpreting this incorrectly. That refers to when
the message has a body. An HTTP GET *request* has no body, and
therefore no Content-Type header. The *response* of an HTTP GET will
have a Content-Type.

A request can have a Content-Type header, but not for GET. A POST will
have a Content-Type header if it has a body.

Jeff

Rémi Arnaud

unread,
Jul 1, 2012, 6:09:39 PM7/1/12
to 3d-...@googlegroups.com
Wondering if we could do this once per 'connection' rather then once per object. 

In other words, connect to server, and then have a short back and forth dialog about what's available at the beginning only, and then use that information in the application when asking for content. (rather than negotiating with each object)

BTW, I made more investigations, and the caching does not work at all with 'Vary'. 

Regards
-- Remi

Jeff Terrace

unread,
Jul 1, 2012, 6:18:09 PM7/1/12
to 3d-...@googlegroups.com
So the idea being that a client would indicate at the beginning of a
session that it wants a particular format, maybe saved in a cookie.
Then, when the client requests a URL like
http://example.com/texture/water it gets back a different response
based on its cookie?

That also doesn't seem like a great idea to me, and it would also
break caching. I think URLs should look more like:

http://example.com/texture/water.png
http://example.com/texture/water.jpg

or:

http://example.com/texture/water?format=png
http://example.com/texture/water?format=jpg

When the client downloads metadata about a mesh, it should receive a
list of textures, and what formats they are available in.

Jeff

Rémi Arnaud

unread,
Jul 1, 2012, 7:19:31 PM7/1/12
to 3drest
No, I was thinking the later, have a manifest giving information about the assets; for example formats, sizes, version, lod, tiling... Databases are good at those queries.
-- Remi

-----Original Message-----
From: Jeff Terrace <jter...@gmail.com>
Sender: 3d-...@googlegroups.com
Date: Sun, 1 Jul 2012 18:18:09
To: <3d-...@googlegroups.com>
Reply-To: 3d-...@googlegroups.com
Subject: Re: [3D-REST] IMVU's binary 3D content delivery format (was: Introduction)

Chad Austin

unread,
Jul 2, 2012, 3:46:23 AM7/2/12
to 3d-...@googlegroups.com
On Sun, Jul 1, 2012 at 2:52 PM, Jeff Terrace <jter...@gmail.com> wrote:
That's important for *responses*, not really for requests.

I agree with Rémi on this one: extensive use of HTTP headers is
cumbersome for clients. It's much easier to have explicit URLs using
query parameters, rather than having to send Accept headers and then
detect what type the server sent back to you.

I've heard that claimed a couple times on this list.  Can you elaborate on the difficulty of setting HTTP headers in requests?

Every HTTP client library I've ever used makes it easy to set HTTP headers on a request.

However, I do understand the value of being able to direct-link to some content in a particular format, even though we don't need it yet at IMVU.  Along those lines, we intend to support a content-type query parameter to override HTTP content type negotiation, a la /some_texture?content-type=image/png.

Let me step up to a higher level for a moment.  We are building a RESTful interface to our catalog of over 6 million pieces of user-generated 3D content.

We will likely consume said content from WebGL (both with and without dxtc support), various mobile devices, and Windows/Mac/Linux desktops.  To load a chunk of 3D content, we can tolerate two HTTP round-trips.  We also benefit from HTTP caching at multiple layers: internal to the data center (varnish, etc.), along the internet infrastructure (CDN, ISPs), and on the customer's computer (browser cache).

We will link to 3D content from various other places in the system.  An obvious example is a user's current outfit.  The RESTful /user service will return a link to the user's current outfit.  The format of an outfit URL is opaque, except that a client can assume it returns the "outfit" content type, which is just JSON pointing to various meshes, materials, textures, a skeleton, perhaps some animations.

If you REQUIRE that a URL contains type information, then that type information bleeds into any linking documents, such as the outfit.

Imagine the following link structure, minus extraneous JSON keys:

service /user/12345 returns:
{current_outfit: '/outfit/abcdefgh'}

service /outfit/abcdefgh returns:
{ objects: [ ..., { texture: '/texture/xyz' }, ...] }

service /texture/xyz always supports PNG and JPEG, say, but optionally crunch/dxtc, dds/dxtc, pvrtc, etc.

If you encode the texture content type in the URL, then the /outfit service (and thus the /user service!) also need knowledge of what content types to return.  That hurts caching.  Ideally you'd have a single /outfit URL to support WebGL clients that support DXTC, WebGL clients that don't, iOS, etc.

When I download metadata about an object, the server should give me
information about what formats the mesh and its textures are available
in, along with URLs for fetching them in the desired format. Let the
application make decisions at a higher level instead of having to mess
with HTTP headers.

That's exactly the problem that HTTP Accept, Vary, and automatic content negotiation solve, while fitting seamlessly into existing infrastructure stacks (CDNs, HTTP accelerators, client-side HTTP caches), so I'd like to hear more specifics about why headers are so painful.

Thanks,
Chad

Chad Austin

unread,
Jul 2, 2012, 4:00:23 AM7/2/12
to 3d-...@googlegroups.com
On Sun, Jul 1, 2012 at 3:09 PM, Rémi Arnaud <re...@acm.org> wrote:
BTW, I made more investigations, and the caching does not work at all with 'Vary'. 

Eh?  That makes no sense.  Vary is exactly how you specify that a request header affects the response content, and thus its cacheability.  Vary is supported by CDNs, Varnish, and browsers*, so I'd like to see some backing citations to support your broad claim that "caching does not work at all with Vary".

I also don't understand how CORS is related to caching.  We've had no problems with CORS either, and we've been using CORS for all of our REST services lately.

* IE9 implements Vary in a somewhat restricted manner that requires the use of etags and causes some spurious requests, but IE9 also doesn't support WebGL, so this detail is somewhat academic.

Alan Chaney

unread,
Jul 2, 2012, 9:53:42 AM7/2/12
to 3d-...@googlegroups.com
I complete agree with Chad's earlier comment that there should be no problem in setting headers in a request. The only situation where that is difficult is any attempt to simply use a browser with GET, which isn't really a valid user interaction with REST, anyway. REST is a programmatic API, and it is easy to set headers with any HTTP bindings I've encountered (Python, C++, Java, Javascript). Many users will want to use XHR in Javascript, and this has a setRequestHeaders() method.

Many REST APIs, including, for example Amazon S3, require that you set headers to manage the request. Personally, I think that it is a good idea to be flexible, and in our Molly asset management system we offer a choice of using headers, content type extension or query parameters to control the response. The server sets the actual content type returned.

For debugging within a browser I recently came across https://github.com/chao/RESTClient for Firefox. The author is planning Chrome and IE versions, apparently. You can perform authentication and set headers with this utility, and send GET, PUT, POST and DELETE commands using a browser.



Alan Chaney
CTO/Founder
Mechnicality, Inc.

Jeff Terrace

unread,
Jul 2, 2012, 12:06:14 PM7/2/12
to 3d-...@googlegroups.com
On Mon, Jul 2, 2012 at 3:46 AM, Chad Austin <ch...@imvu.com> wrote:
> On Sun, Jul 1, 2012 at 2:52 PM, Jeff Terrace <jter...@gmail.com> wrote:
>>
>> That's important for *responses*, not really for requests.
>>
>> I agree with Rémi on this one: extensive use of HTTP headers is
>> cumbersome for clients. It's much easier to have explicit URLs using
>> query parameters, rather than having to send Accept headers and then
>> detect what type the server sent back to you.
>
>
> I've heard that claimed a couple times on this list. Can you elaborate on
> the difficulty of setting HTTP headers in requests?
>
> Every HTTP client library I've ever used makes it easy to set HTTP headers
> on a request.

Sure, but not as easy as setting the URL. It's usually a few extra
lines of code. Not a deal breaker, but it's still extra work.

>
> However, I do understand the value of being able to direct-link to some
> content in a particular format, even though we don't need it yet at IMVU.
> Along those lines, we intend to support a content-type query parameter to
> override HTTP content type negotiation, a la
> /some_texture?content-type=image/png.

This is important, IMO. Being able to link directly to a specific
format of an asset is something we should want.
I would say encode the base URL:

{ objects: [ ..., { texture: '/texture/xyz' }, ...] }

The client can then download /texture/xyz.png or
/texture/xyz?format=png. You can even expose what formats are
available in your metadata response:

{ textures: 'xyz': {url: '/texture/xyz', formats: ['png', 'dds', 'jpeg']} }

>
>> When I download metadata about an object, the server should give me
>> information about what formats the mesh and its textures are available
>> in, along with URLs for fetching them in the desired format. Let the
>> application make decisions at a higher level instead of having to mess
>> with HTTP headers.
>
>
> That's exactly the problem that HTTP Accept, Vary, and automatic content
> negotiation solve, while fitting seamlessly into existing infrastructure
> stacks (CDNs, HTTP accelerators, client-side HTTP caches), so I'd like to
> hear more specifics about why headers are so painful.

Except that a lot of software (caches, browsers) still has broken
implementations of the Vary header.

It makes more sense to me to just allow clients to make the decision
about what format they want to download. The HTTP Accept header is
overly complicated if you read the spec:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html Ask a newcomer
to your API to try and parse this Accept header:

Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
text/html;level=2;q=0.4, */*;q=0.5

There are very few uses of the Accept header out there. It's mostly
just for gzip compression and sometimes for XML vs. JSON response
negotation. Using it for something as complicated as mesh and texture
quality and formats is going to get real ugly real fast. It's much
easier to just tell a client: here's a list of formats. Pick one.

Jeff

R?mi Arnaud

unread,
Jul 2, 2012, 5:24:23 PM7/2/12
to 3d-...@googlegroups.com
Overall, I do like the idea of HTTP header server side negotiation,
although it does make the client code more complex as it needs to
figure out what to do with the response for each query. Providing
access to the exact asset URL is necessary in a lot of use cases
anyways, such as uploading and modifying content. So IMHO the rest-3d
api has to provide this way to get to the asset anyways, which can be
used also with GET. I see no harm to add server side resolution in
addition to client side resolution, but there are some issues that I
would love to better understand

- image formats are not interchangeable. If I encode Z map in an image
I want to get a png. If the server returns a jpeg it would simply not
work. This is just an example, transparency is another, shader program
specific textures is another.
From the discussion I understand that the deeper implication is that
the content would not provide the format information and the client
would be able to figure out what preferred formats to ask for based
solely on which platform it is running on.
I don't see how this can work. Without the content giving more
information to the client on what format is acceptable.


- caching is very important. I understand the theory behind the accept
and vary. In have not yet had the time to check it myself but was told
it does not really work currently. I was told that for caching to work
with CORS, vary need to be set to *. I've seen some issues reported
about server side proxy/caching ignoring the vary parameter completly.
Those can been seen as bugs that will be fixed in the future, but on
the other hand having a specific url does currently work fine with
caching - I have tested that.

Something that I have a hard time to understand how implementation
would work is when using the same resource with different parameters
in the same client application. For example when paging different
sizes of the same image when paging. Does caching work? I mean in
practice, not just theoretically?
What does the client code looks like, I imagine one would have to
carry around all the http header information and do some kind of
compare, as oposed to just referring with the specific url. In
practice I would have to build a unique name for those resources,
looking very much the url that could be used to query for the asset if
I had not used server side content negotiation?

Thanks for helping me understand those issues.

Mark Barnes

unread,
Jul 4, 2012, 3:15:12 PM7/4/12
to 3d-...@googlegroups.com
Hi Jeff,

I dont think the HTTP spec supports your assertions although perhaps I missed a relevent section ...

HTTP 1.1 section 7.1 states that entity-headers refer to the resource identified by the request if no entity body is present (i.e a typical GET). This is exactly the use-case we are talking about I believe (both content-type and accept headers apply). I don't recall any exceptions for this treatment in the spec?

It's an interesting design point to be sure. Any URL that begins with http scheme is an HTTP message while the URI itself is an opaque resource regardless. For URI, media type applies to a representation of the resource not to the resource itself. A URL should refer to the location of an opaque resource that may have zero or more representations (according to the server). URI do provide (scheme dependent) syntax for encoding meta-data and is the option you're favoring for media type.

I guess my point is that HTTP headers trump URI meta-data (by design) when using HTTP scheme and to design accordingly.


Regards,
Mark

Mark Barnes

unread,
Jul 4, 2012, 3:37:28 PM7/4/12
to 3d-...@googlegroups.com
On Mon, Jul 2, 2012 at 12:46 AM, Chad Austin <ch...@imvu.com> wrote:
On Sun, Jul 1, 2012 at 2:52 PM, Jeff Terrace <jter...@gmail.com> wrote:
That's important for *responses*, not really for requests.

I agree with Rémi on this one: extensive use of HTTP headers is
cumbersome for clients. It's much easier to have explicit URLs using
query parameters, rather than having to send Accept headers and then
detect what type the server sent back to you.
I've heard that claimed a couple times on this list.  Can you elaborate on the difficulty of setting HTTP headers in requests?

Every HTTP client library I've ever used makes it easy to set HTTP headers on a request.

However, I do understand the value of being able to direct-link to some content in a particular format, even though we don't need it yet at IMVU.
...
 
If you REQUIRE that a URL contains type information, then that type information bleeds into any linking documents, such as the outfit.
 

I agree with Chad's points.... because as I said in my last post URI are opaque resources with N representations. It is counter to the URI spec and its design to make a URL point to a specific representation (content media type) of a resource. The Web is not brittle thanks in large part to this distinction. Let's not lose it.

ps: I think it's actually anachronistic that ".png" in the path part of a URL conveys any sense of media type. A URL is not a file system path!

Regards,
Mark

Mark Barnes

unread,
Jul 4, 2012, 3:45:14 PM7/4/12
to 3d-...@googlegroups.com
On Mon, Jul 2, 2012 at 9:06 AM, Jeff Terrace <jter...@gmail.com> wrote:
On Mon, Jul 2, 2012 at 3:46 AM, Chad Austin <ch...@imvu.com> wrote:
>
> However, I do understand the value of being able to direct-link to some
> content in a particular format, even though we don't need it yet at IMVU.
> Along those lines, we intend to support a content-type query parameter to
> override HTTP content type negotiation, a la
> /some_texture?content-type=image/png.

This is important, IMO. Being able to link directly to a specific
format of an asset is something we should want.


I have to disagree with the intent here if not the sentiment. A URL should refer to an opaque resource whose server may provide a representation of that resource in a media-type that is (somehow) encoded in the request. A persistent URL (PURL) seems more like what you imply by your statement and is something quote specific in the Web.


Regards,
Mark

Jeff Terrace

unread,
Jul 4, 2012, 4:08:20 PM7/4/12
to 3d-...@googlegroups.com
On Wed, Jul 4, 2012 at 3:15 PM, Mark Barnes <ma...@mechnicality.com> wrote:
> I dont think the HTTP spec supports your assertions although perhaps I
> missed a relevent section ...
>

No, Content-Type is used in an HTTP request only for PUT and POST, not GET. See:
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Requests


On Wed, Jul 4, 2012 at 3:37 PM, Mark Barnes <ma...@mechnicality.com> wrote:
>
> I agree with Chad's points.... because as I said in my last post URI are
> opaque resources with N representations. It is counter to the URI spec and
> its design to make a URL point to a specific representation (content media
> type) of a resource. The Web is not brittle thanks in large part to this
> distinction. Let's not lose it.
>
> ps: I think it's actually anachronistic that ".png" in the path part of a
> URL conveys any sense of media type. A URL is not a file system path!

On Wed, Jul 4, 2012 at 3:45 PM, Mark Barnes <ma...@mechnicality.com> wrote:
>
> I have to disagree with the intent here if not the sentiment. A URL should
> refer to an opaque resource whose server may provide a representation of
> that resource in a media-type that is (somehow) encoded in the request. A
> persistent URL (PURL) seems more like what you imply by your statement and
> is something quote specific in the Web.
>

There's theory and then there's practice. Yes, in theory, a REST URL
should represent an abstract resource, but in practice, having a URL
that returns different representations of the resource based on a
request header is not friendly to the user.

Many people use "Vary: Accept-Encoding" for gzip. It's extremely rare
for anyone to use "Vary: Accept". A lot of inline caches and CDNs are
buggy or just don't bother supporting it properly. The rules for the
Accept and Vary headers are complex and error-prone.

At the very least, the REST API should support both methods of retrieval:

GET /texture.png

vs.

GET /texture
Accept: image/png

If you only support the latter, it makes the interface more difficult to use.

Jeff

Ewen Cheslack-Postava

unread,
Jul 4, 2012, 4:28:16 PM7/4/12
to 3d-...@googlegroups.com
On 07/04/2012 12:37 PM, Mark Barnes wrote:
On Mon, Jul 2, 2012 at 12:46 AM, Chad Austin <ch...@imvu.com> wrote:
On Sun, Jul 1, 2012 at 2:52 PM, Jeff Terrace <jter...@gmail.com> wrote:
That's important for *responses*, not really for requests.

I agree with Rémi on this one: extensive use of HTTP headers is
cumbersome for clients. It's much easier to have explicit URLs using
query parameters, rather than having to send Accept headers and then
detect what type the server sent back to you.
I've heard that claimed a couple times on this list.  Can you elaborate on the difficulty of setting HTTP headers in requests?

Every HTTP client library I've ever used makes it easy to set HTTP headers on a request.

However, I do understand the value of being able to direct-link to some content in a particular format, even though we don't need it yet at IMVU.
...
 
If you REQUIRE that a URL contains type information, then that type information bleeds into any linking documents, such as the outfit.
 

I agree with Chad's points.... because as I said in my last post URI are opaque resources with N representations. It is counter to the URI spec and its design to make a URL point to a specific representation (content media type) of a resource. The Web is not brittle thanks in large part to this distinction. Let's not lose it.

I'd like to see where you're reading that resources *must* be generic like that. It certainly allows for it since the URI is the mapping to an entity, not the entity itself. But that doesn't make a very specific mapping, i.e. 'png version of this texture', somehow invalid. In fact, some URIs are designed for *completely specific* mappings, e.g. magnet links. These map to an entity by hash so there is effectively only one representation which it can resolve to. The same is also perfectly valid and reasonable for http URLs if you *need* to refer to that exact representation.

Resources can be generic or specific. I don't read having http://example.com/resource and http://example.com/resource/format as being "counter to the URI spec". Both serve and important purpose.

I'll link again to this doc which suggests a sane way to handle generic and specific resource URLs: http://www.w3.org/2001/tag/doc/alternatives-discovery-20061101.html

And I'll also link back to my previous post that suggests all of these things should be supported -- generic URLs, specific URLs, and using headers, each for different use cases: https://groups.google.com/d/msg/3d-rest/9EYcyy_qwes/5o-a-b5_ZnMJ



ps: I think it's actually anachronistic that ".png" in the path part of a URL conveys any sense of media type. A URL is not a file system path!


That's just a choice of delimiter, the only effect it has is on what characters you disallow in the rest of the resource name to avoid ambiguity between generic resources without the format specified and the specific resource with the format specified.

-Ewen

Mark Barnes

unread,
Jul 4, 2012, 4:32:09 PM7/4/12
to 3d-...@googlegroups.com
On Wed, Jul 4, 2012 at 1:08 PM, Jeff Terrace <jter...@gmail.com> wrote:
On Wed, Jul 4, 2012 at 3:15 PM, Mark Barnes <ma...@mechnicality.com> wrote:
> I dont think the HTTP spec supports your assertions although perhaps I
> missed a relevent section ...
>

No, Content-Type is used in an HTTP request only for PUT and POST, not GET. See:
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Requests


hehe lol ... wikipedia is not an authoritative source my friend! I will stand by the HTTP spec until convincing proof is offered to the contrary. :)


Cheers,
Mark

Jeff Terrace

unread,
Jul 4, 2012, 4:46:07 PM7/4/12
to 3d-...@googlegroups.com
Wikipedia is great at summarizing, but since you're still not convinced:

Straight from the spec
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17):
"The Content-Type entity-header field indicates the media type of the
entity-body sent to the recipient or, in the case of the HEAD method,
the media type that would have been sent had the request been a GET."

A content-type without an entity body is meaningless. GET requests
have no entity body.

http://stackoverflow.com/questions/978061/http-get-with-request-body
http://tech.groups.yahoo.com/group/rest-discuss/message/9962

Yes, you can put a Content-Type header in a GET request, but it's
*completely* meaningless, as is a body.

Jeff

Ewen Cheslack-Postava

unread,
Jul 4, 2012, 4:47:46 PM7/4/12
to 3d-...@googlegroups.com
On 07/04/2012 01:32 PM, Mark Barnes wrote:

On Wed, Jul 4, 2012 at 1:08 PM, Jeff Terrace <jter...@gmail.com> wrote:
On Wed, Jul 4, 2012 at 3:15 PM, Mark Barnes <ma...@mechnicality.com> wrote:
> I dont think the HTTP spec supports your assertions although perhaps I
> missed a relevent section ...
>

No, Content-Type is used in an HTTP request only for PUT and POST, not GET. See:
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Requests


hehe lol ... wikipedia is not an authoritative source my friend! I will stand by the HTTP spec until convincing proof is offered to the contrary. :)

I'm not sure of the point of this aspect of the discussion. Technically it doesn't look like the spec says you shouldn't put Content-Type on a GET request (or any request that doesn't have a body). Ok, so...

Why does that matter? The only thing Content-Type specifies is the content type of the message body. It's metadata about the request body. There isn't a message body in the GET request. So the content type doesn't matter. It's not like specifying it here would somehow affect what the server returns -- regardless of whether you *can* included, it's not intended to act as a parameter to control the response's content type (and I doubt browsers would even let you add it...).

-Ewen

Mark Barnes

unread,
Jul 4, 2012, 4:54:50 PM7/4/12
to 3d-...@googlegroups.com
Hi Ewen,

Long time since we hung out and talked over designs ... Happy 4th!!

I'm refering to RFC3986 for URI generic spec.. I'm not saying they *must* be nor does the rfc, rather that is how they are described for design purposes. Resources and representations are destinct concepts and yes it's obvious that many implementers get this wrong (or never read the rfc to begin with, i.e. don't care). Specific mappings can be had in this context of course... a good design recognizes that a URL refers to a resource that *may* allow retrieval of a specific representation. I'll offer that a bad one mistakenly believes it is linking directly to a represenation.

Cheers,
Mark

Mark Barnes

unread,
Jul 4, 2012, 4:56:22 PM7/4/12
to 3d-...@googlegroups.com

It does matter and it does apply! Again see http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1


I'm out for today...

Cheers,
Mark
 

Jeff Terrace

unread,
Jul 4, 2012, 6:52:41 PM7/4/12
to 3d-...@googlegroups.com
No, it doesn't. Read it again. That section refers to 14.17 for the
description of the Content-Type field. The description says it applies
only to the entity body. There is no entity body with a GET request.

Mark Barnes

unread,
Jul 6, 2012, 2:57:43 AM7/6/12
to 3d-...@googlegroups.com
uhm it says "... or, if no body is present, about the resource identified by the request."

shrug

m.
Reply all
Reply to author
Forward
0 new messages