Is there a way to limit request frequency and sizes out of the box in ktor? - ktor

Simply, I have methods like post("/login") { ... } and post("/uploadAvatarImage") { ... }, and I want to limit the sizes appropriately. If I were to hand roll this myself, I could either find some way to hook into every request and throw if a rolling rate is higher than acceptable, or create overrides of post to include things like rate limit and size restrictions. It would be nice if this were all definable globally in some of the configuration sections, so I don't have to manually check whether a user supplied a 2 billion character user name.
Is this a feature that exists in ktor? Or anyone have a good example of a nice way to do it, if there exists something better than what I was thinking?

To answer your question about limiting the size, I am assuming in the body of these requests you are deserialising to some kind of data class? If so the valiktor library (link) makes this very easy to add a max size limit on a particular property.
In regards to rate limiting, I wouldn't really expect this from the framework itself, however it seems someone has made a feature for this (link).
It is interesting I mean Spring Boot itself doesn't have rate limiting either but rather its competitor to nginx, Spring Cloud Gateway, has a rate limiting feature. It kind of poses the question of whether it is necessary to think about the architecture of introducing rate limiting at another layer (such as a gateway entry point) before reaching your app.

Related

What is the standard acceptable request/response-timeout for API server (and Why)?

I'm working on developing both web-client and API server. I've been doing some research regarding default timeout, some are at 800ms, others 1200ms. However, I can't find the reason behind the arbitrary number. Can someone help me regarding this? An explanation behind the arbitrary number would be a great help.
Thanks,
TLDR: Please see paragraph starting with "The arbitrary number" in bold below. The rest is just extra info on the topic.
Although you might know this or have already read this in your research, I can share the following ideas:
Typically the timeout is set depending on the expected complexity of a query, the amount of data to be processed, and the expected load of the system when the query occurs (or any other expected operation that may require attention in terms of modifying a timeout). Also, this can be based on something like the number of requests an API makes to other APIs to handle an incoming request(s) and what those expectations might be.
The arbitrary number ("best guess" of whoever developed the software) would typically be expected when planning for a "most requests should complete in some fraction of this time if there is no issue regardless of what happens" or "this isn't anything to worry about" type of scenario. Hence the default values for timeouts are pretty much based on the assumption that they represent the vast majority of "acceptable" completed requests where no issue is present. It is typically set somewhere between "this should be plenty of time" and "there is most likely something terribly wrong with this request, let's end it" and most successful requests pass this test by "default".
In the case that you have operations that may take several minutes and you expect that this can occur without an actual issue being present, you may want to set the timeout higher than the default so your requests don't timeout when there is no actual problem (for example, most commercial APIs have constraints on the number of requests and time in which they must complete so problematic requests don't clog up the system and other reasons as seen by their developers).
Thus, there really isn't a great answer or standard to this aside from just taking a look at the amount of data/requests to be processed, planning for a reasonable ebb and flow of server load, level of optimization of your code compared to the expected load, and so on... It's almost like error-handling but for things that you don't know might happen yet (such as unexpected bugs) but based on things you already know about your system and its expected usage.
Generally, you won't have many scenarios where the timeout really matters all that much but you always want to have one (at least the default) to prepare for the unexpected.
I found the following article that talks about the topic and some of what I mentioned as well if you haven't seen it already:
https://medium.com/#masnun/always-use-a-timeout-for-http-requests-de4da538b9e3
tl;dr - According to SLA [ Service Level Agreement ] mostly. If not, try to optimize the code as much as possible to bring down the time it takes to give out the response in terms of milliseconds
I'll put the answer in layman's terms since it really depends on various factors.
Let's assume you have an API and it performs some operation and gives the result back. It's quite simple and you'll get the response for that under some milliseconds if they don't perform any complex operations.
And when we move into a more and more complex system where one API talks to another, it adds up the time, and the worst-case scenario, first API which started the request might get the final response after 5 seconds, 30 seconds, or even 60 seconds depending on the number of API calls and how good the system is designed.
And we are only considering the happy flow. What if something goes wrong in one of the APIs that gets called internally?
To avoid this bad experience, the clients will make an SLA that requires the company/developers to design the code in such a way that it gives the response within a certain acceptable range.
I came across this conversation once on Google Groups conversation and it might provide some insight.
So to answer the question about the acceptable range, If you don't have an SLA, try to optimize the code as much as possible to bring down the time it takes to give out the response in terms of milliseconds.
Generally 1 Second is considered acceptable. The reason for this and why the suggested numbers vary so much is most APIs have a lockout if you send requests to fast. However, some APIs will let you send requests faster. In my experience all of the APIs I have seen request a 1s(1000ms) delay between requests to prevent overload/accidental DDOS and have a timeout of 30-60sec.
Edit: It is important to mention to not let another request from the same IP be answered if the first one is still waiting as this would make a DDoS easy

In the Diode library for scalajs, what is the distinction between an Action, AsyncAction, and PotAction, and which is appropriate for authentication?

In the scala and scalajs library Diode, I have used but not entirely understood the PotAction class and only recently discovered the AsyncAction class, both of which seem to be favored in situations involving, well, asynchronous requests. While I understand that, I don't entirely understand the design decisions and the naming choices, which seem to suggest a more narrow use case.
Specifically, both AsyncAction and PotAction require an initialModel and a next, as though both are modeling an asynchronous request for some kind of refreshable, updateable content rather than a command in the sense of CQRS. I have a somewhat-related question open regarding synchronous actions on form inputs by the way.
I have a few specific use cases in mind. I'd like to know a sketch (not asking for implementation, just the concept) of how you use something like PotAction in conjunction with any of:
Username/password authentication in a conventional flow
OpenAuth-style authentication with a third-party involved and a redirect
Token or cookie authentication behind the scenes
Server-side validation of form inputs
Submission of a command for a remote shell
All of these seem to be a bit different in nature to what I've seen using PotAction but I really want to use it because it has already been helpful when I am, say, rendering something based on the current state of the Pot.
Historically speaking, PotAction came first and then at a later time AsyncAction was generalized out of it (to support PotMap and PotVector), which may explain their relationship a bit. Both provide abstraction and state handling for processing async actions that retrieve remote data. So they were created for a very specific (and common) use case.
I wouldn't, however, use them for authentication as that is typically something you do even before your application is loaded, or any data requested from the server.
Form validation is usually a synchronous thing, you don't do it in the background while user is doing something else, so again Async/PotAction are not a very good match nor provide much added value.
Finally for the remote command use case PotAction might be a good fit, assuming you want to show the results of the command to the user when they are ready. Perhaps PotStream would be even better, depending on whether the command is producing a steady stream of data or just a single message.
In most cases you should use the various Pot structures for what they were meant for, that is, fetching and updating remote data, and maybe apply some of the ideas or internal models (such as the retry mechanism) to other request types.
All the Pot stuff was separated from Diode core into its own module to emphasize that they are just convenient helpers for working with Diode. Developers should feel free to create their own helpers (and contribute back to Diode!) for new use cases.

REST Handling of Removed Backwards-compatible Functionality

How does Semantic Versioning define the version change required when functionality is removed but the client will not necessarily break?
For example, if I have a resource that accepts a sort param:
/person?sort=name
If I removed the ability to sort, the existing clients could still consume the service (sort just would not be honored). Does SemVer consider this a backwards incompatible change? If not, what rule specifically addresses this situation?
From my perspective existing clients will break - they expect for the result set to be returned in a sorted fashion and it won't be. That means that, quite likely, some web page or app-screen somewhere will display data in a non-sorted fashion even though the user clicked a button asking for stuff to be sorted by name. The client's user experience changes negatively and unexpectedly, even though the application doesn't fall over. As such, you're talking about a breaking-change and so a major version increase.
If you could be absolutely sure that no client used the API element then it might be a different thing - e.g. if you work in a closed world where you can inspect and verify all your clients then you might choose to pretend that the API element never existed and only consider the change a minor or patch change. But 99% of the time it should be a version increase and even in the closed-world situation I'd think that would be an extreme approach that would only be justified in certain circumstances.

Ruminations on highly-scalable and modular distributed server side architectures

Mine is not really a question, it's more of a call for opinions - and perhaps this isn't even the right place to post it. Nevertheless, the community here is very informed, and there's no harm in trying...
I was thinking about ways to create a highly scalable and, above all, highly modular back-end architecture. For example, an entire back-end ecosystem for a large site that had the potential for future-proof evolution into a massive site.
This would entail a very high degree of separation of concerns, to the extent that not only could (say) the underling DB be replaced (ie from Oracle to MySQL) but the actual type of database could be replaced (ed SQL to KV, or vice versa).
I envision a situation where each sub-system exposes its own API within the back-end ecosystem. In this way, the API could remain constant, whilst the implementation could change (even radically) over time.
The system must be heterogeneous in that it's not tied to a specific language. It must be able to accommodate modules or entire sub-systems using different languages.
It then occurred to me that what I was imagining was simply the architecture of the web itself.
So here is my discussion point: apart from the overhead of using (mainly) text-based protocols is there any overriding reason why a complex back-end architecture should not be implemented in the manner I describe, or is there some strong rationale I'm missing for using communication protocols such as Twisted, AMQP, Thrift, etc?
UPDATE: Following a comment from #meagar, I should perhaps reformulate the question: are the clear advantages of using a very simple, flexible and well-understood architecture (ie all functionality exposed as a series RESTful APIs) enough to compensate the obvious performance hit incurred when using this architecture in a back-end context?
[code]the actual type of database could be replaced (ed SQL to KV, or vice versa).[/code]
And anyone who wrote a join between two tables will be sad. If you want the "ability" to switch to KV, then you should not expose an API richer than what KV can support.
The answer to your question depends on what it is you're trying to accomplish. You want to keep each module within reasonable reins. Use proper physical layering of code, use defined interfaces with side-effect contracts, use test cases for each success and failure case of each interface. That way, you can depend on things like "when user enters blah page, a user-blah fact is generated so that all registered fact listeners will be invoked." This allows you to extend the system without having direct calls from point A to point B, while still having some kind of control over widely disparate dependencies. (I hate code bases where you can't find-all to find all possible references to a symbol!)
However, the fact that we put lots of code and classes into a single system is because calling between systems is often very, very expensive. You want to think in terms of code modules making requests of each other where you can. The difference in timing between a function call and a REST call is something like one to a million (maybe you can get it as low as one to ten thousand, if you only count cycles, not wallclock time -- but I'm not so sure). Also, anything that goes on a wire in a datacenter may potentially suffer from packet loss, because there is no such thing as a 100% loss-free data center, no matter how hard you try. Packet loss means random latency spikes in the response time for your application.

WCF Binding Performance

I am using basic HTTP binding.
Does anybody know which is the best binding in terms of performance as thats the key issue for our site?
Depends on where the services are located.
If they're on the same machine, NetNamedPipeBinding should give you the maximum performance.
Otherwise you'll have to choose depending on where they are located, if they have to communicate over the internet, interopability etc.
Soledad Pano's blog has a good flow chart to help with choosing the appropriate bindings depending on situation
This is comparing apples to oranges. If you are using the basic HTTP binding, then there is a basic set of services and whatnot that it is providing, which is different from the services that the WsHttpBinding offers, for example.
Given that, the performance metrics are going to be different, but you also aren't going to get the same functionality, and if you need that particular set of functionality, then the comparison isn't worth doing at all.
Additionally, there are bindings (like the net tcp and named pipe bindings) which might not be applicable at all, but have better performance characteristics.
Finally, your statement about "best performance" indicates that you really aren't looking at it the right way. You have expectations of what your load is during peak and non-peak times, as well as the response times that are acceptable for your product. You need to determine if WCF falls within those parameters, and then work from there, not just say
"I'm looking for the best performance".
You will have to give more requirements for what you are trying to do, and then more light can be shed on it.
A good resource for WCF info:
http://www.codeplex.com/WCFSecurity/Wiki/View.aspx?title=Questions%20and%20Answers&referringTitle=Home
Has a section on choosing bindings for your particular scenario. Is security not an issue? If not then you have more choices available to you.
It's hard to tell what the performance will be without other known factors (server HW, amount of concurrent users, etc.).
HTTP binding will be performing slightly better then HTTPS for example, but binary WCF to WCF communication will be quicker then HTTP for the price of lesser compatibility.
I think you need to provide more details - what is the desired functionality (do you need SOAP messages exchange, or Ajax with JSON?) and expected server load.