DEV Community

Cover image for Practical Advice to Good API Design

Practical Advice to Good API Design

Johanne Andersen on November 24, 2020

During a rare productive youtube session, I came across a talk on How to build good APIs and why it matters by Joshua Bloch (author of Effective Ja...
Collapse
 
linxsoftware profile image
Linx Software

Great post! Having read a gazillion API articles, I compiled this list of API tools

Design
-Postman
-Swagger
-Stoplight

  • Insomnia

Build
-Programming languages

  • Linx

Deploy

  • On-premise: Nginx, Apache, IIS, Linx
  • IaaS: AWS, Azure
  • PaaS: Heroku, Linx

Manage
-Kong
-Azure

  • AWS
Collapse
 
mnaumanali94 profile image
Nauman Ali

Awesome list. I created a list of free API design tools. Could be a nice addition to this awesome list.

linkedin.com/posts/nauman-ali_apis...

Collapse
 
johannea profile image
Johanne Andersen

Thank you! I need to look into some of these technologies. Are there any articles, in particular, you would recommend?

Collapse
 
linxsoftware profile image
Linx Software

I wrote this recently, maybe can give you a good idea on API development

dzone.com/articles/the-quickest-wa...

Collapse
 
tibi profile image
Thiébaut Champenier

Excellent summary, thank you! Nothing new but it's good to read Bloch's advice again and again.

A few errors:

use the most specific input parameter type

It's output, not input

use doubles instead of floats for monetary values

Both are wrong, BigDecimal is a good choice for example.

Collapse
 
johannea profile image
Johanne Andersen

Thank you, I was just repeating what was in the talk and I guess some of it is outdated with regards to monetary values.
For the input values, he does say to "use the most specific input parameter type", but I think it goes for both input and output.

Collapse
 
tibi profile image
Thiébaut Champenier

Bloch would not say such a thing, no.

I've checked his slides, he says

  • Don't use floating point for monetary values: Binary floating point causes inexact results
  • Use double rather than float

There is no relation between his two assertions. double is as bad as float for monetary values. He says so in the talk.

For the input type, he says in the talk "if you accept a collection but blow up unless you're passed a Set, that's broken." And this I agree, but the fix imho should be to make it work with any Collection. Only if not possible, declare the input as Set. We've all been annoyed by APIs accepting only a List when we have a Set that would perfectly work. But I'm not sure I'm qualified to disagree with Bloch even so slightly ;-)

Thread Thread
 
johannea profile image
Johanne Andersen

You are right, I'm sorry, I misread. I'll edit it in the post as well. Thanks for pointing it out!

For the input type, I'm no expert, but I imagine it also depends on the use case. But I completely agree with your point, if it works for any collection, a collection would also be the most specific input type there is. (I would think so at least)

Collapse
 
blacklight profile image
Fabio Manganiello

"Long lists of identically typed parameters can be harmful and very error-prone" - I would argue that this can be a quite language-specific remark. Languages like Python or Perl make it easy to use keyword arguments to circumvent the curse of long function signatures:

def start_camera(device='/dev/video0',
                            resolution=(640,480),
                            color_mode='rgb24',
                            rotation=0,
                            scale=(1, 1), 
                            # ...
                           **kwargs):
    cam = Camera(device=device, ...)

# ...

# Pick only some of the parameters through named arguments
start_camera('/dev/video1', rotation=90)
Enter fullscreen mode Exit fullscreen mode

Although this can be achieved in languages like JavaScript with key-value objects:

const startCamera = (props) => {
    // ...
}

startCamera({
    device: '/dev/video1',
    rotation: 90,
})
Enter fullscreen mode Exit fullscreen mode

And in Java with, as you said, helper classes - and even though such a mechanism is also available in recent versions of Python (@dataclass) I still prefer the named arguments approach because it makes a method signature really self-explanatory.

Collapse
 
johannea profile image
Johanne Andersen

I completely agree with the named parameter approach, but I still think a long list of parameters, especially of the same type is still error-prone since you don't have to use the named parameters (I can only speak for Python and JavaScript).
Plus a long parameter list to begin with usually means bad design. But named arguments definitely make it less error-prone should you choose to go down that path.

Collapse
 
ashishk1331 profile image
Ashish Khare😎

Loved it. Well explained and it covered all the points. Thank you for writing this.🤠

Collapse
 
johannea profile image
Johanne Andersen

Thank you, I'm glad you enjoyed it 😁

Collapse
 
coorasse profile image
Alessandro Rodi

Hi! Nice reading! I also wrote about some useful tips recently. It's targeted to Rails developers but there are some generic learnings as well: dev.to/coorasse/rails-api-be-nice-...

Collapse
 
mnaumanali94 profile image
Nauman Ali

Hey! Great write up.

One point that i’m not sure about is jumping into coding the API. What’s your take on writing an OpenAPI and getting feedback on that? That way you’re iterating on a spec instead of code.

Collapse
 
johannea profile image
Johanne Andersen

Thank you!
I think that is definitely a good idea, especially in the beginning. In the talk, Bloch also suggests writing to the API as a part of developing it. That way you can get a sense of how it is to use the API while you're designing it.
I hope that makes sense

Collapse
 
danmarshall909 profile image
DanMarshall909

SOLID advice :)

Collapse
 
veganaise profile image
Antoine

I had numerous courses about APIs and this article is what I wished to learn!

Collapse
 
johannea profile image
Johanne Andersen

I am really glad you liked it! I highly recommend watching the talk it's based upon too (Under resources)