Hacker Newsnew | past | comments | ask | show | jobs | submit | badbath's commentslogin

I know firsthand just how difficult it is to work with all the disparate APIs for the different hardware providers, particularly with smartlocks. How do you deal with providing an ergonomic API on top of the access management and key/credential granting itself? Each of the APIs has different concepts, e.g. Salto's API has "binary keys", "zones", "access groups", "audit trails", etc...whereas SMARTair has "sites", "locking plans", etc. How do you deal with all of this? In other words, does your API abstract over all the APIs for purposes of setting up access? How would I, for example, given any type of lock, grant keys to a visitor which should expire in one week?


Ohhh, this is such a great question! Also, it's quite clear you’ve seen these systems & their APIs up close, and can appreciate the mess… :)

So I’d say there are two approaches to doing these abstractions. We sort of support both and let the API client decide which way they want to roll.

The first approach consists of stripping away all the “stuff” that stands in the way of controlling a device. We basically just boil everything down to atomic operations on a single device. For example on SaltoKS locks, we let you create access codes directly on a door devices without having to worry about creating users, access groups, schedules…etc. Of course, we have to create these behind the scenes, but we don’t expose them to the API client. Instead we give you simple methods such seam.access_code.create(device_id…etc) that you can use against either an August device or one that’s part of a larger system such as SaltoKS.

The second approach consists of reintroducing the concept of users, access groups, and assigned credentials…etc and to lift the abstraction to entire systems vs just individual devices/nodes. You frankly need to do this if the site owner wants to continue to use their system in a sensible manner (e.g. see list of employees who badged in) or if you want to support more complex forms of credentials (e.g. Google/Apple Wallet).

I think the important thing to recognize is that, at the end of the day, whether you choose abstraction 1 or abstraction 2, these devices/systems all more or less do the same thing. The manufacturer may use slightly different terminology but you can create abstractions from that.

ps: btw for a long-time we made the mistake of spending too much time trying to nail the abstraction on every dimension imaginable. This included features of certain systems that no developers were asking us about. Now we just focus on solving what devs are asking for. That reduces the surface area of how much "stuff" we have to deal with when creating these API interfaces. This is a textbook example of going back to the YC basics of "talk to users" and "build something people want".


How much do I need to know about Linux before taking this course?


A basic knowledge of linux will be very helpful, but I’ll explain in detail issues that I’ve seen crop up in the past.


Would this be faster if we not calculate powerset xs twice? I don't know how GHC works well enough so I ask.


I'm pretty sure GHC will optimize that out since it's a pure function.


That's nuts. All of your code now has to check if err != nil, etc.

Furthermore, the sendEmail and validateEmailForm values are essentially ignored and used only for their possible error values.

Why should I wrote my program as if the thing I'm concerned primarily with is errors? Much better to encode the failure into the type. You could have, for example, some function that returns Either[Error, SendEmailAction] where SendEmailAction is a function that, when called, will perform the effect of sending an email. Now I can deal with the happy path by mapping on the right-biased Either.


This has been discussed in pretty much every golang thread here on HN :)


When I started go, i also thought it was nuts. And it indeed clutters your code a lot. But in the end, i like it.

Golang is a really simple language, but all the simple concepts, and the lack of OOP, forces you to think more about your code. Also you are forced to think about error conditions.

I'm still playing around with it. So i dont have a final opinion on go.


Not if you use Scala. With Scala, you'd just map or for comprehension over the result.


That's what he covers in his third paragraph...


Well, to be fair it's if you use any language that uses some equivalent of the Maybe Monad.


I did for android app. we simply looked at number of installations by country and we had a lot of people asking for their language to be supported. we used google services to do the localization. for us, main thing was simply making all labels, etc make sense for native speakers of the two other languages (beside english) that we added


Thanks. Does your app have any server-side content (apart from user-generated content)?


No, all of the content is user-generated. For this content, we just display it in the language it was submitted. The localization I was talking about is more for static things like buttons and general navigation around app.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: