[Notes] Your coding conventions are hurting you

http://www.carlopescio.com/2011/04/your-coding-conventions-are-hurting-you.html

Alan is very explicit about the idea of methods as goals, something you want to happen, unconcerned about how it is going to happen.

The fundamental reason behind TDD.

If we can’t find a good name, we obviously don’t know enough about either the problem domain or the solution domain.

I would suggest that you focus on class/interface names first. If you can’t find a proper name for the class, try naming functions. Look at those functions. What is keeping them together? You can apply them to… that’s the class name :-).

When Peter wrote that (1993), the idea of an Helper class was mostly unheard of. But as more people got into the OOP bandwagon, they started creating larger and larger, uncohesive classes. The proper OO thing to do, of course, is to find the right cooperating, cohesive concepts. The lazy, fake OO thing to do is to take a bunch of methods, move them outside the overblown class X, and group them in XHelper. While doing so, you often have to weaken encapsulation in some way, because XHelper needs a privileged access to X. Ouch.

Wow, I’ve never paid attention to that since helper class is so much “needed” for every project. Lol

Handler, again, is an obvious resurrection of procedural thinking. What is an handler if not a damn procedure? Why do something need to be “handled” in the first place? Oh, I know, you’re thinking of events, but even in that case, EventTarget, or even plain Target, is a much better abstraction than EventHandler.

Again, eye opening!

Still, at some point people thought it was fine to look at an interface (or at a class), see if there was some kind of “main method” or “main responsibility” (which is kinda obvious if you only have one) and name the class after that. Which is a very simple way to avoid thinking, but it’s hardly a good idea. It’s like calling a nail “Hammerable”, because you known, that’s what you do with a nail, you hammer it. It encourages procedural thinking, and leads to ineffective abstractions.

Unusual perhaps, but that’s because of the common drift toward the mechanics of things and away from concepts (because the mechanics are usually much easier to get for techies).

Sort of calling a concept IDollar instead of Currency.

A List is an IEnumerable (what??) A List is a Sequence (well, all right!)

[Notes] The Ultimate Guide to handling JWTs on frontend clients (GraphQL)

The Ultimate Guide to handling JWTs on frontend clients (GraphQL)
— Read on blog.hasura.io/best-practices-of-using-jwt-with-graphql/

So far, this is the best article I have read that explains and answers questions on JWT (both server and client.)

That’s why it’s also really important not to store JWT on the client, say via cookies or localstorage. Doing so you make your app vulnerable to CSRF & XSS attacks, by malicious forms or scripts to use or steal your token lying around in cookies or localstorage.

So memory only? For cookies, with HttpOnly and Secure, there should be no concern about XSS or man-in-the-middle. Yes, chance of CSRF is still there. So you need anti-forgery. For example, keeping an anti-forgery token in localstorage (since value in localstorage won’t be sent automatically with each request.)

So it really depends on the balance of security vs. cost to keep it absolutely secure.

A very good point has been made in this SO thread.

This is a painful discussion on the Internet. Our short (and opinionated answer) is that backend developers like using JWTs because a) microservices b) not needing a centralized token database.

Indeed yes, the two most important benefits.

This token is issued as part of authentication process along with the JWT. The auth server should saves this refresh token and associates it to a particular user in its own database, so that it can handle the renewing JWT logic.

The refresh token is sent by the auth server to the client as an HttpOnly cookie and is automatically sent by the browser in a /refresh_token API call.

Persisting JWT token in localstorage (prone to XSS) < Persisting JWT token in an HttpOnly cookie (prone to CSRF, a little bit better for XSS) < Persisting refresh token in an HttpOnly cookie (safe from CSRF, a little bit better for XSS).

[Notes] Our journey to type checking 4 million lines of Python

https://blogs.dropbox.com/tech/2019/09/our-journey-to-type-checking-4-million-lines-of-python/

Gradually migrating using mypy.

Once your project is tens of thousands of lines of code, and several engineers work on it, our experience tells us that understanding code becomes the key to maintaining developer productivity. 

Type comments were also handy for Python 2 support, which has no built-in notion of type annotations:

[Notes] Azure Cosmos DB update for August 2019

https://channel9.msdn.com/Shows/Azure-Friday/Azure-Cosmos-DB-update-for-August-2019

Azure Cosmos DB is getting more and more powerful. Now Apache Spark can be enabled. It comes with Jupyter Notebooks. You can work directly on the data. So there is no need to copy the data around. Spark worker can be auto-scaled up and down with your DB. Aggregation query performance improvement is fantastic, both faster and cost less.

[Notes] 6 Lessons we learned when debugging a scaling problem on GitLab.com

https://about.gitlab.com/2019/08/27/tyranny-of-the-clock/

The first step is to look for critical filters to dramatically reduce the area to troubleshoot. Such as type of logs, which server, etc.

Wireshark statistics tools could be super helpful.

If usage pattern aligns with some timing cadence, think scheduled jobs.

If the incoming rate exceeds the limit (measured every millisecond) the new connections are simply delayed. The TCP client (SSH in this case) simply sees a delay before the TCP connection is established, which is delightfully graceful, in my opinion. 

Why? Rate limiting should be used for defensive needs, where it prevents from handling the unexpected requests. But in this case, those requests are expected and expect to be processed.

When you choose specific non-default settings, leave a comment or link to documentation/issues as to why, future people will thank you.

That applies to all things non-default, such as “magic numbers,” workarounds, tricks, possible valid values, etc.

[Notes] Why Amazon DynamoDB isn’t for everyone

https://read.acloud.guru/why-amazon-dynamodb-isnt-for-everyone-and-how-to-decide-when-it-s-for-you-aefc52ea9476

So when you combine inexperienced devs, the lack of a clear plan for how to model a dataset in DynamoDB, and a managed database service that makes it really easy to ingest a lot of unstructured data — you can end up with a solution that spirals out of control even at a small scale.

Quick and dirty prototypes done with try and error models would be the best use case for DynamoDB. At the same time, building a real product directly on top of a working prototype is a dangerous approach and set up for failure.

A relational database will do most anything you need at small scale. It might take a little longer to set up initially than DynamoDB, but the well-established conventions of a SQL implementation can protect you from a lot of wasted time down the road.

The initial time it took can take you way further than you would expect if you head down the RD SQL way.

So if your application is using too many RCUs on a single key, you either need to over-provision all the other partitions (expensive), generate a ton of “Throughput Exceeded” errors (not ideal), or figure out how to decrease access to that key.

One takeaway here is that DynamoDB isn’t necessarily suited to datasets that have a mix of hot and cold records.

End of the date, if it is a good use case for DynamoDB, it should also be a good use case for Azure Table, which in my opinion, even much simpler and much more scalable. And Azure Table is truly performance-provision-free.

Business value trumps architectural idealism every time.

That kind of decision making can tell a mature architect from a mediocre one, especially for the line of business software development.

This is why Lynn Langit has more or less abandoned NoSQL as a solution for small and medium-size businesses.

It depends on the balance. Breaking schema changes in SQL is a huge pain. Plus if CI/CD, no-downtime deployment is a must-have, involving changes to the index, for a relatively large database, SQL will take a bigger hit. But anyway, to do all the above, even NoSQL won’t be trivial.

[Notes] Calculating Derived State in JavaScript Using Selectors

https://nick.scialli.me/calculating-derived-state-in-javascript-using-selectors/

We can use selectors to solve this issue. Selectors are functions that take state as a property and return the derived state value. Let’s see if we can create a selector to replace our allowedIn property.

Our decision is not just based on our state object anymore, but is based on the result of another selector as well. This is where we start using higher order functions to compose selectors from other selectors. 

Many selector libraries (e.g., Reselect for Redux) include additional functionality to memoize selector results.

Great examples that explain why we need Selectors and how to use them for calculating derived State (like a computed property.)

[Notes] How Hasura saved us $50,000

https://medium.com/cresta-engineering/how-hasura-saved-us-50-000-7cfe8e7909e9

front-end stack of React, TypeScript, and Apollo.

React gets more tractions. TypeScript is still not out-of-the-box supported. At the same time, more and more start-ups using TypeScript with React together. May it worth the effort to add that extra layer? So that the project is more maintainable?

Hasura markets their product as a “GraphQL-out-of-the-box.” It’s a standalone server that sits between your database & client. This differentiates Hasura from other offerings (like Prisma), and puts it closer in spirit to projects like PostGraphile.

More like a self-hosted managed BaaS.

But this isn’t how Hasura works. Instead, every GraphQL operation you send to the server is transpiled to raw SQL.

Sounds pretty straightforward on paper. That is no “magic.” But just looking at the generated SQL, may be useful for performance tuning troubleshooting, but not sure how much that will help to migrate to other vendors when decided Hasura is not the best option.

simply state the data requirements of your UI, and let a library handle everything else.

Very nice to have!

Besides remote schemas (a feature also available in a few GraphQL solutions), Hasura offers a clever feature: create any view or stored procedure, and Hasura can automatically generate GraphQL operations. Subjectively, complex data transforms are far easier to write and maintain in SQL than they are in JavaScript or TypeScript. Being able to go from creating the view to querying it in the client in mere seconds feels feels almost like cheating.

Not quite sure what kind of “data transforms” the author refers to but doing anything in SP never felt to be enjoyable. SQL is not a language to implement business logic. Creating views may still seem fine to me.

Now, that same button is simply a matter of updating the client, clicking a few things in the Hasura UI, then testing & deploying. We’ve cut the amount of server code we have to maintain by 2/3rds, allowing us to spend that time building more cool stuff for our users.

For CRUD liked operations, that seems very handy. Not sure about other buttons with more complex logic behind.