Skip to content

Static Loading of Service Namespaces#106

Merged
hiranya911 merged 4 commits intomasterfrom
hkj-module-loading
Oct 17, 2017
Merged

Static Loading of Service Namespaces#106
hiranya911 merged 4 commits intomasterfrom
hkj-module-loading

Conversation

@hiranya911
Copy link
Copy Markdown
Contributor

Admin SDK monkeypatches service namespaces (Auth, Messaging etc.) to the parent admin namespace at SDK initialization. The index.ts file calls a set of register*() functions, which imports the services, and attaches them to admin. However, for most services this both unnecessary, and error prone.

This PR gets rid of the monkeypatching for all services but RTDB. There are several benefits for this change:

  1. We can get rid of a significant amount of boilerplate code, whose sole purpose was to facilitate dynamically injecting various services into the admin namespace.
  2. Services can be statically exposed from admin in a way that is both simple and type safe. Services will continue to be loaded/initialized on-demand (e.g. Auth service will not get initialized until admin.auth() is invoked).
  3. Integration between services and the admin namespace can be verified with unit tests.
  4. We can expose arbitrary types from the admin namespace without having them implement the FirebaseServiceInterface. This is useful when exposing external types such as Firestore from the admin namespace.

Copy link
Copy Markdown
Contributor

@jshcrowthe jshcrowthe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems pretty good, if you'd take a look at the few comments I had that'd be great.

Comment thread src/firebase-namespace.ts Outdated
ApplicationDefaultCredential,
} from './auth/credential';
import {Firestore} from '@google-cloud/firestore';
import * as _ from 'lodash/object';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT you are bringing this in to do:

_.assign()

There is a native JS version of this called Object.assign, it may be able to trim a dependency for you.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brilliant! Done. Thanks for the tip.

};
const reference = admin.firestore().collection('cities').doc()
return reference.set(expected)
return Promise.resolve()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the rationale behind this change?

It seems like you've added an extra step in the chain unnecessarily.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to allow any errors thrown by admin.firestore.FieldValue to be caught in the catch block. I noticed that errors thrown outside the promise chain, cause the test suite to come to a halt.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhh gotcha. Ok, then yeah this is fine then.

Copy link
Copy Markdown
Contributor

@jshcrowthe jshcrowthe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@hiranya911 hiranya911 merged commit c28ac52 into master Oct 17, 2017
@hiranya911 hiranya911 deleted the hkj-module-loading branch October 17, 2017 23:03
Copy link
Copy Markdown

@phra phra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using a getter function breaks mocks depending on es6 module import.. ref: https://railsware.com/blog/2017/01/10/mocking-es6-module-import-without-dependency-injection/

Comment thread src/firebase-namespace.ts
AppErrorCodes.INTERNAL_ERROR,
'INTERNAL ASSERT FAILED: Firebase auth() service has not been registered.',
);
get auth(): FirebaseServiceNamespace<Auth> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line breaks es6 import mocking..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants