# The Global Object g

> Everything your code gets in API Maker through g - the request (headers, params, query, body, auth, event data), the response (status, content type, output, headers, errors), g.sys for the database, system and cache APIs, the logger and the shared space.

Source: https://docs.apimaker.dev/v1/docs/pre-defined-terms/global-object-g.html

Every piece of code you write in API Maker, a custom API, a hook, an event listener, a scheduler, a migration, a process initializer, a test case, is a function of one argument :

```typescript
import * as T from 'types';
import * as db from 'db-interfaces';

async function main(g: T.IAMGlobal) {
    const rows = await g.sys.db.getAll<db.mongodb.shop.IProducts>({ instance: 'mongodb', database: 'shop', collection: 'products' });
    g.logger.log(rows.length, 'products');
    return rows;
}
module.exports = main;
```

| | |
|---|---|
| `g.req` | What came in : headers, params, query, body, event data, the opened tokens. |
| `g.res` | What goes out : status code, content type, output, headers, errors, warnings. |
| `g.sys` | The APIs of API Maker from code : `db`, `db.gen`, `system`, `cache`, and `test` inside a test case. |
| `g.logger` | `debug`, `log`, `info`, `warn`, `error` : shown with the response on the testing pages, kept by the [log profiles](https://docs.apimaker.dev/v1/docs/logs/log-profile.html). |
| `g.shared` | A place for values which pre hook, API and post hook of one request share. |

## g.req

| Key | Holds |
|---|---|
| `headers` | The request headers, editable : a pre hook can set `x-am-content-type-response` for the whole call. |
| `params` | The path parameters : `instanceName`, `database`, `collection`, `id`, `primaryKey`, `field` and `order` of distinct, `tenantUsername` for a [multi-tenant](https://docs.apimaker.dev/v1/docs/features/multi-tenant.html) request… |
| `query` | The query parameters as an object : `find`, `select`, `limit`… editable in a pre hook, which is how [row level security](https://docs.apimaker.dev/v1/docs/authorization/handle-role-based-permissions.html) is done. |
| `body` | The body, editable. |
| `eventData` | The data of the event, in an event listener. |
| `auth` | The opened tokens : `authAMUser` (the API user), `authAMDB` (the person, from a DB auth provider), `authCustom`, `authGoogle`, `authAWS`, `authAzure`. |
| `reqInfo` | `url`, `apiCategory`, `reqMethod` and `apiInfo` (`id`, `name`, `schemaType`) : which API is running. |
| `isApiRequestFromUser` | `true` for an HTTP request, `false` for a call made from code. |

**Who is calling**

```typescript
const person = g.req.auth.authAMDB;      // the row of your users table, minus its password
const apiUser = g.req.auth.authAMUser;   // name and groups of the API user
```

## g.res

| Key | Holds |
|---|---|
| `statusCode` | `T.EStatusCode.OK` (200), `CREATED`, `NO_CONTENT`, `BAD_REQUEST`, `UNAUTHORIZED`, `FORBIDDEN`, `RESOURCE_NOT_FOUND`, `INTERNAL_SERVER_ERROR`… Set by your code, it wins over the one of the API. |
| `contentType` | `T.EContentType.JSON` (default), `XML`, `YAML`, `TEXT`, `HTML`, `OCTET_STREAM`. |
| `output` | The answer. In a post hook, the answer of the API, editable. A custom API returns its output instead. |
| `headers` | Headers to add to the reply. |
| `errors`, `warnings` | The lists of the reply. |
| `shared` | Same as `g.shared`. |

**An HTML page from a custom API**

```typescript
g.res.contentType = T.EContentType.HTML;
return '<h1>Hello</h1>';
```

- To send a file, return an object with `__am__downloadFilePath` or `__am__downloadFileOrFolderPaths` : see [files](https://docs.apimaker.dev/v1/docs/apis-all/custom-apis/user-created-custom-api.html#files).

## g.sys

| Part | Holds |
|---|---|
| `g.sys.db` | The [schema APIs](https://docs.apimaker.dev/v1/docs/apis-all/overview.html) of any table : `getAll`, `getById`, `query`, `saveSingleOrMultiple`, `masterSave`, `updateById`, `updateMany`, `replaceById`, `removeById`, `removeByQuery`, `aggregate`, `count`, `distinct`, `distinctQuery`, `arrayOperations`, `getAllByStream`, `queryByStream`. [Examples](https://docs.apimaker.dev/v1/examples/sys/db/getAll.html). |
| `g.sys.db.gen` | The same calls on the generated APIs, without schema : `getAllGen`, `queryGen`… [Examples](https://docs.apimaker.dev/v1/examples/sys/db/gen/getAllGen.html). |
| `g.sys.system` | The [system APIs](https://docs.apimaker.dev/v1/examples/sys/system/system.html) : `encrypt`, `decrypt`, `hash`, `getToken`, `getSecret`, `callExternalApi`, `executeQuery`, `getTableMeta`, `createIndexes`, `dropIndexes`, `getIndexes`, `emitEvent`, `emitEventWS`, `isValidDataForTable`, `isValidDataForCustomAPI`, `isValidDataForThirdPartyAPI`, `multiTenantInstanceUpdated`, `isValidConnectionString`. |
| `g.sys.cache` | Your own keys in Redis and the cache resets : `getKey`, `setKey`, `removeKey`, `resetCacheDB`, `resetCacheCustomApis`, `resetCacheSystemApis`, `resetCacheThirdPartyApis`. [Examples](https://docs.apimaker.dev/v1/examples/sys/cache/setKey.html). |
| `g.sys.test` | In a [test case](https://docs.apimaker.dev/v1/docs/test-cases/test-cases.html) only : `runCustomApi`, `mock`, `clearMocks`, `calls`. |

- Every `g.sys.db` call takes the same `headers` and `queryParams` an HTTP call takes, and runs with the groups of the API user of the request. Hooks are skipped unless you pass `skipHookRunning: false`.
- Pass `true` as the last argument (`getFullResponse`) to get the whole `{ success, data, errors, … }` envelope instead of `data`.

## g.logger and g.shared

```typescript
g.logger.log('order ', order._id);         // with the response on the testing pages, in the logs of a log profile
g.logger.error('payment failed : ', e.message);
g.shared.count = 234;                      // set in a pre hook…
const count = g.shared.count;              // …read in the post hook of the same request
```

- `debug`, `log`, `info`, `warn` and `error` write the same line : the level is not kept. The arguments are joined without a separator, objects are printed as indented JSON. The calls are synchronous, no `await`.
- For an error, log `e.message` or `e.stack`.
- On the native process (`runOnNativeProcess`), `console.log` is not captured : use `g.logger`.

## Related

- [Custom APIs](https://docs.apimaker.dev/v1/docs/apis-all/custom-apis/user-created-custom-api.html) · [Pre hooks](https://docs.apimaker.dev/v1/docs/apis-all/hooks/preHook-api.html) · [Code examples](https://docs.apimaker.dev/v1/examples/index.html) · [Cheat sheet](https://docs.apimaker.dev/v1/docs/cheat-sheet.html)
