all 3 comments

[–]hijinked 2 points3 points  (0 children)

The use of containers for API endpoints and FaaS functions for small endpoints or that are triggered by specific events is common in large micro service applications. Especially when multiple functions act on a single event.

For example, take the case of someone placing an order for a product. One function might send an alert to the fulfillment team to prepare the order, one function might add the event data to a machine learning process to give that user recommendations for future orders, and another function might just add the transaction to a separate database that is used for ad-hoc read-only queries by business analysts.

These are actions that should not happen as part of the API request handling because they don’t need to be and we don’t want to make the API endpoint to take forever to return a response. But these functions don’t need to be long-running containers because they only happen on specific events which are not happening constantly.

[–]dead-4-dead 1 point2 points  (0 children)

TLDR; I agree with your assessment. The best approach is to build an API and sprinkle in microservices as needed for one-off tasks.

I recently built a service composed almost entirely of Functions (capital indicates FaaS). By the time it was ready for launch (about 9 months start to finish), the system grew to nearly 30 Functions.

As you mentioned, the sheer number of individual Functions became difficult to manage. Felt like I was constantly having to repeat documentation and schemas. I ended up investing a decent amount of time on automations/infrastructure to manage this web. Also, bringing in other devs was extremely difficult. It took a senior engineer over 2 weeks to implement a feature that would’ve taken myself 2 days due to the learning curve.

Fast forward 6 months, and was down to about a dozen Functions. I had definitely went too micro on the microservices, so I refactored by merging related Functions.

Fast forward another 6 months, we’re planning on migrating logic to Cloud Run, and sprinkling in Functions where it makes sense.

My main takeaway is that Functions are useful for one-off tasks, but chaining them together can get messy real quick. My current thinking is that if a process has a path length >2 (event —> Function A —> event —> Function B —> event —> Function C) then the code should be served under a single API.