ChrisAtWork's comments

ChrisAtWork | 7 years ago | on: Cloudflare 1.1.1.1 iOS app

Same. My home Unifi network is all integrated with PiHole and does DNS over HTTPS to CF.

Having the 1.1.1.1 on my phone is great except when I'm at home and want it disabled.

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

Why do you think HTTPS would fix this?

For the TLS case, there are enough MITM proxies, both in the Enterprise and elsewhere, to make this a real concern. There are also API Aggrigators which are effectively MITM and need to be taught to "play-well" with custom headers.

Certainly in the consumer case HTTPS would keep a majority of consumer facing ISPs from header-stripping, but there is still a pretty big hole.

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

The "?api-version" approach in the doc is there for exactly the reason you call out. Azure uses this approach.

By omitting "/v1.0" from the path it makes the actual URL's far more durable, as they're not version dependent. There are pros and cons to this, as there is with everything. In Azure's case it's great, as you can then use URLs as resource identifiers and put ACL's on them. If they were versioned via the path, this wouldn't work.

Other services, such as XBox, and (very old) Azure, put the API version in a custom header (x-ms-version, for example). This proved to be extremely problematic, and every team that does this had stories of all the problems it caused and then spends time removing it.

I've never seen a detailed proposal for putting API version in the Content-Type header, and will go look.

The content-type header does seem to have many of the same drawbacks as putting the version in a header (any header). For example, people could not make queries from a browser just by entering a URL as there is no way to specify a header. Nor could someone bookmark an API GET request, which is also quite handy.

Ease of use is huge, and I am in the camp that a version in the URL (path or parameter) is much easier in every way than a header. Every with curl, it's easier (I can never remember how to specify headers w/o the man page).

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

I don't think I've ever seen delta's done at-scale with actual temporal tables, but rather with transaction Id's of some sort.

For example (based on the doc) when you register a delta link, there's a row written to Azure Tables saying, "owner:iheart2code, deltaToken:foo, lastRecordIdSeen:123".

When you then make the Delta request, we look up "foo" for you, find that the last id you've seen is 123, and then only give you records from the transaction table with an id larger than that.

Temporal is always a can of worms, as clocks are impossible to keep in sync and there are endless race conditions.

Making the delta tokens causal, rather than temporal, is the way to go. Anything else is brutal in the distributed systems world...

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

There's nothing wrong with RPC APIs. Other than being "Not Cool" due to the legacy of SOAP, they can deliver some very nice value.

Various RPC mechanisms like Bond and Protocol Buffers (and more recently GRPC) are trying hard to make RPC cool again. Personally, I hope they succeed, as REST (like any technology) doesn't work for everything.

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

There are a number of examples to cite showing what you say isn't true.

Allowing totally arbitrary OData $filter expressions does lead to problems, but recent versions of OData have a nice mechanism to describe (and discover) what can be filtered on. This is both tooling and developer (for consumption) friendly.

There are many examples of teams providing OData API heads without using SQL as the data store. Teams do this using EXO, various Azure data stores, and custom stores.

Using (for example '$filter=productName eq cupcakes') isn't leaking any weird abstractions, but is giving clients and tooling a nice means to filter a list.

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

That particular example was chosen not because of OData, but because it required someone to type in a horribly long set of alphanumeric codes.

There's no way a human can effectively type that, nor is there any real way to look at it and figure out what it's doing. That the URL happens to use ODAta (because that's what Exchange does) is not really relevant.

The overriding factor, as called out in the doc, is that URLs should be human understandable. That's not to say canonical id's can't be used, but a big base64 encoded string is not recommended.

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

Delta queries are pretty easy, assuming you have a rich data store behind your data.

As others have said, your data store needs to be able to say, "Show me changes since XYZ". Most of the Big Apps can do that, and from there the problems is one of API Semantics.

This doc addresses the API Semantics, rather than the application design. To try to solve the design problem would be impossible as every application is different.

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

It turns out that uploading files is hard. Files come in a variety of sizes, networks sometimes don't work, browser processes come-and-go, some users expect restart semantics, some don't...

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

"Success With Info" is something that just causes problems.

The number of examples we found of "Success with Info" going horribly wrong was abundant. Turns out checking return codes is something people have failed to do pretty much since the invention of the return code...

ChrisAtWork | 9 years ago | on: Microsoft REST API Guidelines

The API version header has a few problems.

1. Older proxies used to remove/strip headers they don't understand. 2. Frameworks and libraries don't always give access to n non-standard headers, meaning they just can't used. 3. It's harder for humans to look at a request and see what's going on.

page 1