And then you don't really need most of it, and one thing you need is so utterly complicated, that it is stupid (no RoI) to even bother being compliant.
And truly, less is more.
I'd like to ask seasoned devs and engineers here. Is it the normal industry-wide blind spot where people still crave for and are happy creating 12 different description of the same things across remote, client, unit tests, e2e tests, orm, api schemas, all the while feeling much more productive than <insert monolith here> ?
I was however impressed with FastAPI, a python framework which brought together API implementation, data types and generating swagger specs in a very nice package. I still had to take care of integration tests by myself, but with pytest that's easy.
So there are some solutions that help avoid schema duplication.
It depends on the system in question, sometimes it's really worth it. Such setups are brittle by design, otherwise you get teams that ship fast but produce bugs that surface randomly in the runtime.
I'm not sure what would lead to this setup. For years there are frameworks that support generating their own OpenAPI spec, and even API gateways that not only take that OpenAPI spec as input for their routing configuration but also support exporting it's own.
I'm joking, but I did actually implement essentially that internally. We start with TypeScript files as its type system is good at describing JSON. We go from there to JSON Schema for validation, and from there to the other languages we need.
Schema validation and type generation vary by language. When we need to validate schemas in JS/TS land, we're using `ajv`. Our generation step exports the JSON Schema to a valid JS file, and we load that up with AJV and grab schemas for specific types using `getSchema`.
Watch out, OpenAPI is now 3 versions deep and supports both JSON and YAML.
YAML made me miss JSON. JSON made me miss XML.
same goes for java vs php/python
But boy, how messy spaghetti don't we get for it, sometimes.
(Invent their own, badly, at first. Sigh.)
https://www.codeproject.com/Articles/1186940/Lisps-Mysteriou...
But then, as the project evolves, you actually discover that these models have specific differences in different layers, even though they are mostly the same, and it becomes much harder to maintain them as {common model} + {differences}, than it is to just admit that they are just different related models.
For some examples of very common differences:
- different base types required for different languages (particularly SQL vs MDW vs JavaScript)
- different framework or language-specific annotations needed at different layers (public/UNIQUE/needs to start with a capital letter/@Property)
- extra attached data required at various layers (computed properties, display styles)
- object-relational mismatches
The reality is that your MDW data model is different from your Database schema and different from your UI data model (and there may be multiple layers as well in any of these). Any attempt to force them to conform to be kept automatically in sync will fail, unless you add to it all of the logic of those differences.
But I don't like the micromanagement of field encoding formats, and I don't like the HTTP3 streaming stuff that makes it impossible to directly consume gRPC APIs from JavaScript running in the browser, and I don't like the code generators that produce unidiomatic client libraries that follow Google's awkward and idiosyncratic coding standards. It's not that I don't see their value, per se*. It's more that these kinds of features create major barriers to entry for both users and implementers. And they are there to solve problems that, as the continuing predominance of ad-hoc JSON slinging demonstrates, the vast majority of people just don't have.
A lot of people just do whatever comes to mind first and don't think about it so they don't get stuck with analysis paralysis.
curl -fail
Handling failure might be the real hardest programming problem ahead of naming and caches and such. It boggles my mind the hate people have for Exceptions which at least make you "try" quite literally if you don't want the system to barrel past failures, some seem nostalgic for errno and others will fight mightily with Either<A,B> or Optional<X> or other monads and wind up just barreling past failures in the end anyway. A 500 is a 500.1. Catch exceptions third-party code and talking to the outside world right away.
2. Never catch exceptions that we throw ourselves.
3. Only (and always) throw exceptions when you're in a state where you can't guarantee graceful recovery. Exceptions are for those exceptional circumstances where the best thing to do is fail fast and fail hard.
(I have been offering REST’ish and gRPC in software I write for many years now. With the REST’ish api generated from the gRPC APIs. I’m leaning towards dropping REST and only offering gRPC. Mostly because the generated clients are so ugly)
REST is just too "floppy", there are too many ways to do things. You can transfer data as a part of the path, as query parameters, as POST fields (in multiple encodings!), as multipart forms, as streaming data, etc.
There has been no lack of heavyweight, pre-declare everything, code-generating, highly structured, prescriptive standards that sloppyREST has casually dispatched (pun fully intended) in the real world. After some 30+ years of highly prescriptive RPC mechanisms, at some point it becomes time to stop waiting for those things to unseat "sloppy" mechanisms and it's time to simply take it as a brute fact and start examining why that's the case.
Fortunately, in 2025, if you have a use case for such a system, and there are many many such valid use cases, you have a number of solid options to choose from. Fortunately sloppyREST hasn't truly killed them. But the fact that it empirically dominates it in the wild even so is now a fact older than many people reading this, and bears examination in that light rather than casual dismissals. It's easy to list the negatives, but there must be some positives that make it so popular with so many.
Care to list them? REST mania started around early 2000-s, and at that time there was only CORBA available as a cross-language portable RPC. Microsoft had DCOM.
And that was it. There was almost nothing else.
It was so bad that ZeroC priced their ICE suite based on a PERCENTAGE OF GROSS SALES: https://web.archive.org/web/20040603094344/http://www.zeroc.... Their ICE suite was basically an RPC with a human-designed IDL and non-crazy bindings for C/C++/Java.
Then the situation got WORSE when SOAP came.
At this point, anything, literally anything, that didn't involve XML was greeted with enthusiasm.
From the top of my head, OData.
Of course, REST won handily. We're not in this environment anymore, thankfully, and REST now is getting some well-deserved scrutiny.
OData officially started out in 2007. Roy Fielding's thesis was published in 2000.
They appeared almost simultaneously, for the very same reason: REST by itself is too vague and unreliable.
Arguably the closest thing to a prescriptive winner is laying OpenAPI on top of REST APIs.
Also, REST defined as "A vaguely HTTP-ish API that carries JSON" would have to be put later than that. Bear in mind that even after JSON was officially "defined" it's not like it instantly spread everywhere. I am among the many people that reconstructed something like it because we didn't know about it yet, even though it was nominally years old by that point. It took years to propagate out. I'd put "REST as we are talking about it" as late 200xs at the earliest for when it was really popular and only into the 2010s as to when you started expecting people to mean that when they said "Web API".
They won inside large companies: Coral in Amazon, Protobufs/gRPC in Google, Thrift in Facebook, etc. And they are slowly spreading outside of them.
OpenAPI is indeed an attempt to bring some order into the HTTP RPC world, and it's pretty successful. I'm pretty sure all the APIs that I used lately were based on OpenAPI descriptions.
So the trend is clear: move away from loosely-defined HTTP APIs into strict RPC frameworks with code generation because this is a superior approach. But once you start doing it, HTTP becomes a hindrance, so alternatives like gRPC are gaining popularity.
> Also, REST defined as "A vaguely HTTP-ish API that carries JSON" would have to be put later than that.
Ruby-on-Rails came out in 2005, and Apple shipped in 2006. REST-ful APIs were one of its major selling points ( https://web.archive.org/web/20061020014807/http://manuals.ru... ).
AWS S3 API, designed around the same time, also was fully REST-ful. This was explicitly one of its design goals, and it was not really appreciated by most people.
My meta point is that it is easy for programmers to come to the conclusion that all that should exist is the stuff that large companies use, as I see so many people believe, but if you try to model the world on that assumption you end up very frustrated and confused by how the real world actually works. You can't push a highly proscriptive, very detailed, high up-front work methology out on everyone. Not because it's a bad idea per se, or because it "wouldn't work", but because you literally can't. You can't force people to be "better" programmers than they are by pushing standards on them.
My gut leans in the direction of better specifications and more formal technologies, but I can't push that on my users. It really needs to be a pull operation.
Oh, for sure. A company can just mandate something internally, whether it's a good idea or not. But superior approaches tend to slowly win out on merit even in the wider world. Often by standardizing existing practices, like OpenAPI did.
And I believe that strict prescriptive APIs with code generation are superior. This is also mirrored by the dynamic and static typing languages. I remember how dynamic languages were advertised in early 2000-s as more "productive" than highly prescriptive C++/Java.
But it turned out to be a mistake, so now even dynamic languages are gaining types.
It's the question of long-term consequences for supportability and product evolution. Will the next person supporting the API know all the hidden gotchas?
But if you have multiple targets, or unusual compilers, or don't enjoy working with build systems, stay away from complex stuff. Sure, REST may need some manual scaffolding, but no matter what your target is, there is a very good chance it has JSON and HTTP libs.
So you can't rely on having structured errors for common codes such as 401/403/404, it's very typical to get unstructured text in payloads for such errors. Not a few REST bindings just fail with unhelpful serialization exceptions in such cases.
Which are...terrible.
Example: structured schema, but no way to require fields.
Make 5 decisions like that and you lost 31/32 of the market.
A vague architecture style is not competition to a concrete framework. At best, you're claiming that the competition to gRPC is rolling your own ad-hoc RPC implementation.
What I expect to happen now is an epiphany. Why do most developers look at tools like gRPC and still decide it's a far better option to roll their own HTTP-based RPC interface? I mean, it's a rational choice for most. Think about that for a moment.
You have all the permutations that sail under the name "REST" to some degree, where there seems to be no rules and everyone does something different. And then you have an RPC mechanism that is about two orders of magnitude tigher and people complain about not having required fields? How? Why? What are they on about?
I mean, if you write validation code for every type, by hand, you will probably still have to do less overall work than for REST'ish monstrosities. But since you have a lot more regularity, you can actually generate this code. Or use reflection.
How much time do people really spend on their interface types? After the initial design I rarely touch them. They're like less than a percent of the overall work.
I think there is some degree of confusion in your reply. You're trying to compare a framework with an architecture style. It's like comparing, say, OData with rpc-over-HTTP.
I'm aware this is an unappealingly rustic reality, but it is nonetheless the reality experienced by most.
Besides in the practical world we are able to observe, REST isn't even an architectural style: it is several architectural styles multiplied by every possible permutation of how you address a dozen or more different concerns. Necessitating disambiguation whenever you talk about it. First to state the obvious, that it isn't really what Fielding described, then on to communicating what vector describes your particular permutation of choices.
It's okay. We don't need to pretend any of us care about REST beyond as an interesting academic exercise.
"2025-07-10T09:48:27+01:00"
That contains, by my quick glance, at least 8 fields of information. I would argue the one field it does not carry but probably should is the _name_ of the timezone it is for.At some point you need real time aware libraries and whatever language you use they've been through several iterations of them (Javascript Date, moment, dayjs, ...) because they got it wrong the first time and probably the second time to.
With ISO 8601 it is easy to get the yyyy, yyyy-mm, hh and other things you might work with primitive tools (awk). Getting the day of the week or the time involved is not hard which gets you to the chronological rosetta stone
https://en.wikipedia.org/wiki/Julian_day
which is a multiplier and and offset away from Unixtime except for all those leap seconds and whatnot. With Unix timestamps comparison is easy and differences are easy and even knowing it is Thorsday is easy; they don't sort as strings but GNU sort has a -n option, only trouble is it is a bunch of twisty little numbers that look alike.
What do you think primitive types are supposed to be?
type JSON =
string |
number |
boolean |
null |
JSON[] |
{[name: string]: JSON}Since ISO 8601 costs 133 CHF I suspect hardly anybody has actually read it, I think if you wanted something that supports all the weird stuff you might find somebody wrote it in 390 assembly.
CORBA is less "incoherent", but I'm not sure that's actually helpful, since it's still a huge mess. You can most likely become a lot more proficient with RESTful APIs and be more productive with them, much faster than you could with CORBA. Even if CORBA is extremely well specified, and "RESTful" is based more on vibes than anything specific.
Though to be clear I'm talking about the current definition of REST APIs, not the original, which I think wasn't super useful.
Circa 2006 I was working on a site that needed to calculate sales tax and we were looking for an API that could help with that. One vendor uses SOAP which would have worked if we were running ASP.NET but we were running PHP. In two days I figured out enough to reverse engineer the authentication system (docs weren't quite enough to make something that worked) but then I had more problems to debug. A competitive vendor used a much simpler system and we had it working in 45 min -- auth is always a chokepoint because if you can't get it working 100% you get 0% of the functionality.
HTTP never had an official authentication story that made sense. According to the docs there are basic, digest, etc. Have you ever seen a site that uses them? The world quietly adopted cookie-based auth that was an ad-hoc version of JSON Web Tokens, once we got an intellectually coherent spec snake oil vendors could spam HN with posts about how bad JWT is because... It had a name and numerous specifics to complain about.
Look at various modern HTTP APIs and you see auth is all across the board. There was the time I did a "shootout" of roughly 10 visual recognition APIs, I got all of them working in 20-30 mins except for Google where I had to install a lot of software on my machine, trashed my Python, and struggled mightily because... they had a complex theory of authentication which was a barrier to doing anything at all.
Worse is better.
I have no idea where you got that idea from. I'm yet to work in a project where any service doesn't employ a mix of bearer token authentication schemes and API keys.
I lost the thread...are we talking websites or APIs?
Both use HTTP, but those are pretty different interfaces.
What I object to about eg xml-rpc is that it layers a second RPC protocol over HTTP so now I have two of them...
It’s a bit odd to say fielding “won the war” when for years he had a blog pointing out all the APIs doing RPC over HTTP and calling it REST.
He formalised a concept and gave it a snappy name, and then the concept got left behind and the name stolen away from the purpose he created it for.
If that’s what you call victory, I guess Marx can rest easy.
I'm not sure the "name was stolen" or the zealot concept actually never got any traction in production environments due to all the problems it creates.
That is a false dichotomy. Fielding gave a name to a specific concept / architectural style, the concept got ignored (rightly or wrongly, doesn’t matter) while the name he coined got recycled for something essentially entirely unrelated.
RPC systems were notoriously unergonomic and at best marginally successful. See Sun RPC, RMI, DCOM, CORBA, XML-RPC, SOAP, Protocol Buffers, etc.
People say it is not RPC but all the time we write some function in Javascript like
which does a and on the backend we have a function that looks like with some annotation that explains how to map the URL to an item call. So it is RPC, but instead of a highly complex system that is intellectually coherent but awkward and makes developers puke, we have a system that's more manual than it could be but has a lot of slack and leaves developers feeling like they're in control. 80% of what's wrong with it is that people won't just use ISO 8601 dates.