Skip to Content
1
Jan 24, 2023 at 08:29 AM

How to invoke /mtx/v1/metadata/csn/ from within my application?

96 Views

Hi,

I'm working with old mtx (not mtxs).
I'm able to call the metadata service via url, e.g. `/mtx/v1/metadata/csn/<tenantId>`.

I cannot invoke the service from within my CAP application.

Cause the metadata service is a regular CAP service I expected to be able to call the above via

  • SELECT
  • srv.run
  • srv.get
  • srv.send
  • ...

Whatever I tried I get an error. The reason for the error is that the context is not set as expected by the service implementation.

This is the error I get

TypeError: Cannot read properties of undefined (reading 'setHeader')

One of my attempts:

const mdSrv = cds.services.MetadataService;
const {csn: csnEntity} = mdSrv.entities  
const tx = mdSrv.tx(req)  // I know that srv.tx(req) is deprecated, was just a try
try { 
  const qry = SELECT.from(csnEntity).where({tenantId: req.tenant})
  // need to run tx.run with the second parameter cause it is expected by the service
  const csnPromise = tx.run(qry, {tenantId: req.tenant})
  // const csnPromise = tx.get('MetadataService.csn').where({tenantId: req.tenant})
  const csn = await csnPromise 
  console.log(csn)
} catch (err: any) {
  log.error(`error reading Tenant metadata CSN `, err);
}
The error is thrown cause in line 29 of file `node_modules/@sap/cds-mtx/lib/api/metadata/index.js` context._.res is supposed to be set which isn't when I call the service as mentioned above.
async function _createReply(context, metadataType, contentForTenantId) {
    const { tenantId } = context.data;
    logger.debug(`Reading metadata of type ${metadataType} for tenant: ${tenantId}`);

    HttpHelper.checkMetadataScopeAndRespond(context);
    await SecurityHelper.checkAuthorization(context, tenantId);

    const timestamps = await Tenant.getTimestamps(tenantId);
    const eTag = HttpHelper.getETag(timestamps);
--------> here the error occurs. context._.res is not set  <-----------
    context._.res.setHeader('eTag', eTag);

    if (HttpHelper.checkFor304(context._.req, eTag)) {
        context._.res.status(304);
        return context.reply('Not Modified'); // avoid generic 404 of runtime, response is not sent
    }

    const content = contentForTenantId(tenantId);
    return context.reply(content);
}
Shouldn't I be able to call the service in this way?