I was going through asynchronous apex and reading it made me confused at one point. In future methods, we cannot pass sojects for reasons future methods being executed at a later point of time, by the time it is executed the sboject data could be stale. But, at the same time, the more advanced queuable apex accepts sobjects. Why is it so? The same reason is applicable for queuable apex also right? kindly clarify.
The possibility of data going stale is not why future methods do not accept sObject parameters.
Id values are future-compatible primitives and can also be stale, if, for example, the record is deleted prior to executing the future method.
All asynchronous code must be concerned about the validity of the data it is passed relative to the current state of the database. This is true across Batch, Queueable, and Scheduled Apex, and for future methods. There's no difference in that concern across all types of asynchronous processing in Salesforce (or, indeed, in other development environments).
Future methods and Queueable Apex simply are different implementations with different capabilities, future being rather older. Neither shields you against changes to the database state between enqueuing and execution, and the difference in accepted parameters isn't due to a difference in that respect.
Batchable, future, and queueable were basically three versions of the same feature request from customers. Initially, customers wanted a way to process bulk data asynchronously. We were given Batchable. Customers then complained that while batchable was great for mass processing, it was too "bulky" when all you wanted was simple asynchronous method calls, so we were given future.
Compared to batchable, you didn't need a separate top-level class, you didn't need to construct an object, you could use it up to 50 times per transaction, and you didn't need to call a special method to invoke it. However, it was also simplified, as you no longer received a "job Id", and you couldn't pass in complex object graphs (which improved efficiency and code design).
Queueable methods were implemented last, and became a hybrid of the two features, offering the ability to monitor jobs and handle complex objects, but without the overhead of Batchable, which required three asynchronous methods to process just a single record, which was why future methods were invented to begin with.
So basically, future methods can't handle them because customers of the time wanted a more lightweight asynchronous feature, and future was designed to address those needs in a way that allowed the best performance.
There are 2 kinds of Integrations.
1) That wants to know what was the State of the records at a given point in time when DML/Operation happened. When a transaction happened what is the state of the records, we need to sync it to the external system.
2) That wants to know what was the latest state of the record. It doesn't not matter how many updates have happened , when sending data to external system, we want latest data.
Back when there was no Queuable, for 1st type of Integration, people used to Serialize Sobjects into JSON string and pass it to the future method and do callout.
SF realized this is a proper use case, and started supported Passing of complex objects natively, now its upto devs to decide if they wanna query data or use serialized sobject data passed to Queueable.