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: 
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.
I asked a similar question to Chris Richardson ([www.microservices.io](http://www.microservices.io)). The result was:

#### Option 1

You use something like websockets, so the microservice1 can send the response, when it's done.

#### Option 2

microservice1 responds immediately (OK - request accepted). The client pulls from the server repeatedly until the state changed. Important is that microservice1 stores some state about the request (ie. initial state "accepted", so the client can show the spinner) which is modified, when you finally receive the response (ie. update state to "complete").