Question: If I have a bottom tab navigator and I the screens within that navigator to navigate to a modal which will be truly full-screen (covering `SafeAreaView`), how do i I do that? From what i understand, `AppContainer` has to be rendered within `SafeAreaView`, if I'm using `SafeAreaView`. So that makes it tricky to use a modal outside of `SafeAreaView`. 

```
const Tabs = createBottomTabNavigator(
  {
    Home,
    ScreenA,
    ScreenB,
    ScreenC,
  },
  {
    tabBarOptions: {
      safeAreaInset: { bottom: 'never' },
    },
  }
);

const TabsAndModal = createStackNavigator(
  {
    Tabs,
    Modal,
  },
  {
    mode: 'modal',
    headerMode: 'none',
    initialRouteName: 'Tabs',
  },
);

const AppContainer = createAppContainer(TabsAndModal);

const App = () => {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: 'blue' }}>
      <AppContainer />
    </SafeAreaView>
  );
};

```

This causes the modal to slide up from the bottom, but it starts at the `SafeAreaView` on an iphone X, so the blue background is visible just below. What is the right way to do this, so that the modal slides up from the very bottom of an an iphone x and the tabs are still rendered within `SafeAreaView`?

Answer: 
It's a good question. To answer, you have to imagine the server running one thread at a time. Making a request to a microservice via RestTemplate is a blocking request. The user clicks a button on the web page, which triggers your spring-boot method in microservice1. In that method, you make a request to microservice2, and the microservice1 does a blocking wait for the response.

That thread is busy waiting for microservice2 to complete the request. Threads are not expensive, but on a very busy server, they can be a limiting factor.

RabbitMQ allows microservice1 to queue up a message to microservice2, and then release the thread. Your receive message will be trigger by the system (spring-boot / RabbitMQ) when microservice2 processes the message and provides a response. That thread in the thread pool can be used to process other users' requests in the meantime. When the RabbitMQ response comes, the thread pool uses an unused thread to process the remainder of the request.

Effectively, you're making the server running microservice1 have more threads available more of the time. It only becomes a problem when the server is under heavy load.
I would take another look at your architecture. In general, with microservices - especially user-facing ones that must be essentially synchronous, it's an anti-pattern to have `ServiceA` have to make a call to `ServiceB` (which may, in turn, call `ServiceC` and so on...) to return a response. That condition indicates those services are tightly coupled which makes them fragile. For example: if `ServiceB` goes down or is overloaded in your example, `ServiceA` also goes offline due to no fault of its own. So, probably one or more of the following should occur:

* Deploy the related services behind a facade that encloses the entire domain - let the client interact synchronously with the facade and let the facade handle talking to multiple services behind the scenes.
* Use MQTT or AMQP to publish data as it gets added/changed in `ServiceB` and have `ServiceA` subscribe to pick up what it needs so that it can fulfill the user request without explicitly calling another service
* Consider merging `ServiceA` and `ServiceB` into a single service that can handle requests without having to make external calls

You can also send the HTTP request from the client to the service, set the application-state to `waiting` or similar, and have the consuming application subscribe to a `eventSuccess` or `eventFail` integration message from the bus. The main point of this idea is that you let daisy-chained services (which, again, I don't like) take their turns and whichever service "finishes" the job publishes an integration event to let anyone who's listening know. You can even do things like pass webhook URI's with the initial request to have services call the app back directly on completion (or use SignalR, or gRPC, or...)

The way we use RabbitMQ is to integrate services in real-time so that each service always has the info it needs to be responsive all by itself. To use your example, in our world `ServiceB` publishes events when data changes. `ServiceA` only cares about, and subscribes to a small subset of those events (and typically only a field or two of the event data), but it knows within seconds (usually less) when `B` has changed and it has all the information it needs to respond to requests. Each service literally has no idea what other services exist, it just knows events that it cares about (and that conform to a contract) arrive from time-to-time and it needs to pay attention to them.