Live data from Hacker News

Problems with Swagger

blog.novatec-gmbh.de

41–50 of 163 posts

Re: Problems with Swagger

#41
While Swagger might not be perfect (some pain points are addressed with OpenAPI v3) it works IMHO pretty well for us (Zalando) and myself doing API first:

* use a decent editor to write the YAML e.g. https://github.com/zalando/intellij-swagger * do not write any boilerplate code and do not generate code (if that's possible in your env), e.g. by using https://github.com/zalando/connexion (Python API-first) * follow best practices and guidelines to have a consistent API experience, e.g. https://zalando.github.io/restful-api-guidelines/

Most importantly Swagger/OpenAPI gives us a "simple" (everything is relative!) language to define APIs and discuss/review them independent of languages as teams use different ones across Zalando Tech.

Re: Problems with Swagger

#42
post #10

I really like the idea of HATEOAS but I have never seen hypermedia controls done in the wild across any companies I've worked for nor on any client projects. I think it's very cool but a lot of development patterns don't consider it.

I agree that HATEOAS is never deployed anywhere, but I think I'd go further than that. It's impossible for me to see how it would be possible to write a HATEOAS client, and I can't in practice see anyone doing so. Optimizing for HATEOAS seems to me to be optimizing for entirely the wrong metrics, and a complete waste of development time and effort.

every web browser you use is a hateoas client

you get some html with embedded links and then the browser automatically goes and fetches css, js, images...

the remaining links it just presents to you, the user, to follow or not as you choose

hateoas is not a complicated idea. it's not meant to replace SOAP or gRPC or thrift. it's something else

Re: Problems with Swagger

#43
post #21

Earlier quoted context omitted.

I agree that HATEOAS is never deployed anywhere, but I think I'd go further than that. It's impossible for me to see how it would be possible to write a HATEOAS client, and I can't in practice see anyone doing so. Optimizing for HATEOAS seems to me to be optimizing for entirely the wrong metrics, and a complete waste of development time and effort.

A few counterpoints as I drift by: The HAL hypermedia format is in use at Comcast, powering the Xfinity TV API. Not only does it take advantage of hypermedia and HATEOAS, it also splits requests/responses in order to make the most use of HTTP caches. https://boston2016.apistrat.com/speakers/ben-greenberg Dunno if you're serious about not seeing how one could write a HATEOAS-driven client library or if I'm being troll…

I'm definitely not trolling - it's just that's not how clients work.

I don't write a client by doing a random walk through the API until I get to the information I need, I want to call the API that I know I need to give me the information that I want, and for performance, I want it all to be returned on a single call ideally.

e.g. If I want user B's playlist, I don't want to have to crawl:

/friends/ => ['b': { 'links': {'info': '/friends/619'} }]

/friends/619 => {'links': {'playlist': '/friends/619/playlist' } }

/friends/619/playlist

Re: Problems with Swagger

#44
post #10

I really like the idea of HATEOAS but I have never seen hypermedia controls done in the wild across any companies I've worked for nor on any client projects. I think it's very cool but a lot of development patterns don't consider it.

I agree that HATEOAS is never deployed anywhere, but I think I'd go further than that. It's impossible for me to see how it would be possible to write a HATEOAS client, and I can't in practice see anyone doing so. Optimizing for HATEOAS seems to me to be optimizing for entirely the wrong metrics, and a complete waste of development time and effort.

> Optimizing for HATEOAS seems to me to be optimizing for entirely the wrong metrics, and a complete waste of development time and effort.

It depends, it's just a way to reduce coupling between a webservice and its client apps. Instead of hardcoding all the URL endpoints into the client, the client has to follow the links provided by the webservice instead. If this layer of indirection has advantages for you depends on your use case. You could compare it to using DNS instead of static IPs. Static IPs work fine but you end up with more coupling than using DNS.

Re: Problems with Swagger

#45
post #24

Earlier quoted context omitted.

I agree that HATEOAS is never deployed anywhere, but I think I'd go further than that. It's impossible for me to see how it would be possible to write a HATEOAS client, and I can't in practice see anyone doing so. Optimizing for HATEOAS seems to me to be optimizing for entirely the wrong metrics, and a complete waste of development time and effort.

> It's impossible for me to see how it would be possible to write a HATEOAS client, and I can't in practice see anyone doing so. There's nothing complicated about a client that understands Hypermedia links. You start at the root, it'll give you a set of links to follow, and you recurse. Here's a browser that can take a HATEOAS-compatible API and will let you work your way through the API: http://dracoblue.github.io/h…

I meant a user friendly client, not something aimed at API developers. Sure you can create something which is aimed at Developers, but it's not presenting the data in a way any user would understand, or in a way that a UX expert can flex.

Fundamentally, your display logic should not be linked to your API schema, but HATEOAS essentially enforces that, because you can't predict what links will be available.

Re: Problems with Swagger

#46
post #37

Earlier quoted context omitted.

I had these same issues. It took me considerably more time and effort to write a Swagger spec and get the UI to actually behave than it did to write my entire API and some simple docs in markdown. I also tried out the "codegen" and a few other projects that generate boilerplate from a spec (for Python) - the code it generated was frustrating, lengthy, and much more complex than the simple endpoints that I quickly wro…

> It took me considerably more time and effort to write a Swagger spec and get the UI to actually behave than it did to write my entire API and some simple docs in markdown. How long did it take to write API consumer libraries in twenty languages and update every one on API change? If you don't care about that, then Swagger isn't a good idea for you. But I'd think really hard about whether you should care about it if…

Is whatever value people are getting out of client libraries provided by something generic like http://unirest.io ?

When does it make sense to issue API-specific client libraries for a plain ole RESTful API?

Re: Problems with Swagger

#47
post #37

Earlier quoted context omitted.

I had these same issues. It took me considerably more time and effort to write a Swagger spec and get the UI to actually behave than it did to write my entire API and some simple docs in markdown. I also tried out the "codegen" and a few other projects that generate boilerplate from a spec (for Python) - the code it generated was frustrating, lengthy, and much more complex than the simple endpoints that I quickly wro…

> It took me considerably more time and effort to write a Swagger spec and get the UI to actually behave than it did to write my entire API and some simple docs in markdown. How long did it take to write API consumer libraries in twenty languages and update every one on API change? If you don't care about that, then Swagger isn't a good idea for you. But I'd think really hard about whether you should care about it if…

One could argue that clients can roll their own damn client implementations, and that autogenerating client libraries is the folly. This is just REST, no?

Re: Problems with Swagger

#48
post #44

Earlier quoted context omitted.

I agree that HATEOAS is never deployed anywhere, but I think I'd go further than that. It's impossible for me to see how it would be possible to write a HATEOAS client, and I can't in practice see anyone doing so. Optimizing for HATEOAS seems to me to be optimizing for entirely the wrong metrics, and a complete waste of development time and effort.

> Optimizing for HATEOAS seems to me to be optimizing for entirely the wrong metrics, and a complete waste of development time and effort. It depends, it's just a way to reduce coupling between a webservice and its client apps. Instead of hardcoding all the URL endpoints into the client, the client has to follow the links provided by the webservice instead. If this layer of indirection has advantages for you depends…

If I remove the reference to a link in the response, it doesn't remove the clients need to:

a) know how to retrieve that link (i.e. what resource do I need to retrieve in order to get that response)

b) requirement for that link to exist (they still need that link).

Requiring that a client know that to get data Bar, they need to retrieve resource A, follow the link at foo[n]._link to retrieve resource B, and then following the link at _link.bar feels like a total non starter, and actually increases coupling.

Re: Problems with Swagger

#49
post #36

My problem with Swagger is almost the opposite... it solves the problem (APIs are very complicated to use!) by embracing this complexity with more complexity and more tools. Rather, I believe the solution is a push to just have simpler APIs. It's crazy to me that it's harder to write a Swagger file than it is to write the API itself. And there's a lot of tooling that benefits from Swagger, but... I've found they all…

Do people write Swagger files by hand? That sounds awful. I was under the impression everyone used tools like I use in Clojure (compojure-api[0] and ring-swagger[1]). [0] https://github.com/metosin/compojure-api [1] https://github.com/metosin/ring-swagger

I didn't realize Swagger was meant to be an intermediate format.

Re: Problems with Swagger

#50
post #32

Earlier quoted context omitted.

REST, if one insists on using it, should really be layered over top of something saner like gRPC or Thrift. Personally, I've always found REST troublesome and overhyped. There's always a few incidents where you spend hours trying to figure out why something isn't working before realizing you had the wrong method on the request. There's no reason the thing you actually want to do to a resource should be tucked away in…

What HTTP servers and clients are you using that don't clearly log the request method? I've never seen one where it's easier to read the body of the request than the method.

How about urllib, the Python default?

    def handle_thing(thing):
        r = urllib.request.Request(url='example.com',
                                   data={'stuff': 1})
        return urllib.request.urlopen(r)
Just one example.

I know the tooling has improved somewhat since REST has become extremely common, so this is less of an issue now than it used to be (for example, most people use the Python requests module now, which makes it harder to use the wrong method (though many other HTTP libs still have the older urllib-style design)), but it's still annoying in principle. Combine with the fact that people tend to have different ideas about what the HTTP verbs and response codes mean, and it's pretty yucky.

Compare with Thrift, where you define an interface, list the possible exceptions, and generate stubs that auto-handle all of this communication exchange for you. All you have to do is make sure that you're calling the correct function, which should be pretty obvious.

This differs from setting the correct method in the HTTP headers in a couple of ways: first, HTTP clients usually assume a default method of GET. With a different protocol, there is no default "method", your action has to be defined somewhere. There will be no assumption (unless you code something implicit like this on top).

Second, a more conventional method has increased code locality, meaning the code that affects the operation is likely to be in the same source file/area. You'll normally be calling an ordinary function name like SaveThing inside the application logic flow, and it will be easier to debug, easier to realize the problem, etc.; the operation to perform is not tucked away in some other contraption that affects the headers.

Is it possible to design REST codebases so that such errors are hard to cause? Sure. But why do it the REST way and make it harder on yourself?

It should be just as easy to see what function you're asking the API to perform on a resource as it is to see what you're sending it. The operation I want to perform is an intrinsic part of what I'm doing. There's no reason to separate it and make it hard. I'd even prefer url-based actions, like example.com/string_save, because then at least the resource and operation are defined in the same spot.

A simple JSON envelope that has an "operation" key separate from a "data" key would make this easy, but then it's not in your header anymore, so it's not "real REST".

Post reply on HN