How can I use vendor-specific MIME-TYPES for "individually tagged" REST APIs

I am developing a RESTful API. I am currently considering using types of MIME-specific providers to convey semantics and values, as well as a “contract” between the client and server.

So, for example, application / vnd.mycompany.person + xml means that the data in question is the xml that represents the person.

I have a requirement to make this API "closed", which means that the reseller can, in turn, provide the API to his client without his client, knowing that this is a service of my company. The way this will work is that my company will host the main api on the generic URL, i.e. www.example.com/api, then my company will use CNAME to point our domain name to this URL , and our resellers could do the same.

Internally, all resource references will be relative from the root of the API, and therefore will respect the actual URL that is used.

HOWEVER, I don't want to understand / support arbitrary MIME types for specific providers, so what should be part of the "mycompany" example of the MIME type above?

+6
source share
2 answers

The HTTP specification says :

The use of unregistered media types is prohibited.

I used to use “custom” media types in my platform, but this caused problems with user agents (browsers, cURL, wget, etc.) that do not recognize content.

You can try to get a registered custom media type, but (A) takes some time; (B) itd takes quite a while before user agents recognize the type, if ever; (C) you indicated that you do not want the company name to always be present in any way.

As an alternative to “custom” media types, I recommend using media type options instead; theyre a blessed way to add additional content information to media types.

Using parameters, your media type may be application/xml; mycompany-schema=person application/xml; mycompany-schema=person or maybe just application/xml; schema=person application/xml; schema=person .

+4
source

I saw a couple of frameworks and tutorials that recommend a particular mime type to "solve" problems, making your REST interface "really RESTful" just because it can be done and somehow it makes it kosher for the REST service.

One of the problems with this approach is that by its nature it is hacking or tricking to “make it work” the way you want it when the whole transition point to the hypermedia-driven REST service is changing the model of your API and service and change how you approach the problem. Tinting the “acceptable” or allowed but not recommended HTTP value for Content-Type like telling the starving Venezuelans that rats are fish, so they can eat them without sin during Lent. Is there something wrong with rat food if that's all you have? Probably no. But is his fish pretending to be a fish? Of course not. If you need a contract-driven interface, use RPC or SOAP, or even a custom mime provider type. But do not point to the specification and say that it is Rest, because in the end you eat a rat, and everyone knows it, and you only lie to yourself.

The second problem is that you are losing the actual benefits of the hypermedia-driven interface when you cut corners. Immediately, you had problems with user agents, and your own server should jump over hoops or simply abandon it because the mime type was unfamiliar. That's because you thought you could have it both ways, when it’s not about impressing your customers with claims to a true Rest service or making the download a little easier by dropping (obviously valuable for some contexts) the extra weight of the contract - This influenced the way your service really interacted with external customers.

Finally, I really don't understand how a particular type of mime provider really applies a contract better than a specific endpoint? All the sites that mention this technique seem to just be relieved that this option exists and, frankly, a little smug and happy that they use it as if they know it is technically “naughty”, but it just fixes it . What is the fix? In your case, why don't you just add your inbound person request / content:

 POST /myRestService/people 

and if they have another request, refer to another endpoint destined for this different data type? If you need the does_something method, could you either go:

 GET /myRestService/people/personID_123/does_something 

or

 GET /myRestService/people/does_something/personID_123 

depending on the exact context?

And just so that I don’t feel that it’s actually useless, any disappointment or anger is not directed at you or your question at all, but everyone has developed for the “solution” of the mime-type seller and obsession for “officially approved and printed” Roy Fielding as a valid REST service, "which, apparently, can not even provide anyone with a working public example, leaving only a sense of urgency to accept it immediately, taking any necessary shortcuts, and we can deal with shame and finger pointing later when we de We really fix problems with arrows.

+2
source

Source: https://habr.com/ru/post/894141/


All Articles