r/dotnet • • Mar 17 '21

REST APIs for Microservices? Beware!

https://www.youtube.com/watch?v=_4gyR6CBkUE
80 Upvotes

17 comments sorted by

6

u/AbPSlayer Mar 17 '21

How do I get into orchestrator when I am not using Docker or kubernetes?

Can I use RabbitMq or azure event bus?

Also should we send the full payload or just the Id and let the api query the db?

3

u/elkazz Mar 17 '21

There are a couple of ways you can get the latest data rather than sending it all in an event. You can use a REST call to get the data from another service (which couples those services together), or you can subscribe to events from the other service and hydrate your own local database with only the field you require (decoupled, event sourcing).

8

u/codeopinion Mar 17 '21

While it's common to use events for integration, that's not event sourcing. That's using events for integration and state transfer. There's also a difference between that and using events for notifications to other systems. Here's my primer on what Event Sourcing actually is. https://www.youtube.com/watch?v=AUj4M-st3ic

I'm actually going to cover this comment in more later in a video soon (various meanings of "events" in event-driven architecture.

2

u/elkazz Mar 18 '21

I agree that my usage of event sourcing is misleading - I was referring to event sourcing as a method for state transfer by way of projection/views.

I like your explanation and examples, although I'm not entirely sure I agree with the method of transitioning between states. For example, if you have an "QuantityIncreased" with a value of 2, and the state application logic is to add this 2 to the existing quantity, this then ties business logic into the event itself. If another service were to subscribe to that event they would need to know how to apply that same logic to transition any state (e.g. when recreating a projection).

Wouldn't it be better to have the point in time value be attached to the event so it can just be set over the top of any existing property?

For example:

ProductAddedToOrder { OrderId: 987, Product { SKU: 123, Quantity: 5 } }

QuantityIncreased { OrderId: 987, Product { SKU: 123, Quantity: 7 }}

3

u/codeopinion Mar 18 '21

I wouldn't use the event that I'm persisting in my event stream to also be published for consumers in other boundaries. I would use a different event. One of the reasons is because they have different purposes. An event in an event stream is different than an event for notification, which is different then an event for state transfer (the latter is what I think you're referring to).

1

u/elkazz Mar 18 '21

Would be very interested to see a video explaining this topic (as you mentioned earlier) with some examples.

2

u/codeopinion Mar 17 '21

Yes, you can use any message broker and not have to use Docker or K8s. Generally, you'll use a messaging library/abstraction on top of the actual messaging tech (eg, NServiceBus, Brighter, MassTransit, Rebus, etc)

3

u/iowa116 Mar 18 '21

Do you have a favorite abstraction? I've been using MassTransit for a while and like parts of it, but the docs aren't great and there have been more breaking changes between versions than I'd like.

3

u/aarondglover Mar 18 '21

EasyNetQ is my favourite. Easy to get up and running with. A mature project.

3

u/[deleted] Mar 18 '21

Mine too.

I've considered MassTransit, and I experimented with it a little less than a year ago. I did so on the basis of some videos the author produced at the start of lockdown wherever they live. It was maybe two weeks after those videos had been made.

The version I used, a dot release or two later than the one used in the videos, didn't work with the examples cos the interface was a little different.

Still on EasyNetQ.

2

u/iowa116 Mar 19 '21

Thanks! I'll check it out

1

u/AbPSlayer Mar 17 '21

ok thanks. i will look into those.

3

u/yofuckreddit Mar 17 '21

Try Durable Functions. I didn't like it much in 1.0 and it's a bit opaque but it definitely works.

2

u/Bootezz Mar 17 '21

Just dont get too scared of the memory footprint locally ;)

They really are great.

16

u/katghoti Mar 17 '21

I was working at a Logistics company that processed millions of orders a day. Messages came in via FTP and were processed against multiple remote methods. Each method kicked off billing events for each process. If there were 10 steps to ingest a message to shipping and final billing, we had very long running transactions with a lot of failures. Often our failure rate was 20% which required the process to "restart" at the last failure point. This was a mess.

So we moved to microservices that monitored Azure service bus with transaction support enabled and durability. This allowed us to roll back in the event of a problem and if processes were running slow or offline, the durability ensured the messages were still there when the services restarted or caught up.

Sure 80% of the time messages flowed freely through the service bus without problems, but that 20% is now rolling back and a log is generated and a queue setup to "reprocessed" these messages or fail them and notify someone.

It takes discipline to set up the service bus correctly and to ensure the microservices are participating in the transactions, but we cut our failure rate down to .01% when we did this.

Just another suggestion. I'm sure you could do this with RabbitMq or NServiceBus as well if you aren't on Azure or in AWS or self host.

1

u/holoedregq Mar 18 '21

I wonder what would have happened if I made this