smartcontractkit / external-adapters-js

Monorepo containing JavaScript implementation of external adapters
MIT License
271 stars 304 forks source link

How to request a non-default endpoint not using ws when WS_ENABLED=true #1570

Open vnavascues opened 2 years ago

vnavascues commented 2 years ago

Hi, I'd like to know what's the best way to deal with an EA that has:

For instance total-burned and price endpoints of the coinmetrics-adapter have to request /v4/timeseries/asset-metrics which does not support ws.

This is the result of requesting any of these coinmetrics-adapter endpoints with WS_ENABLED=true:

curl --header "Content-Type: application/json" --request POST --data '{"id":"1","data":{"endpoint": "total-burned", "asset": "ETH" }}' http://localhost:8080

{"jobRunID":"1","status":"errored","statusCode":400,"error":{"name":"AdapterError","message":"Required parameter base must be non-null and non-empty","feedID":"{\"data\":{\"endpoint\":\"total-burned\",\"asset\":\"ETH\"}}"}}

Is it possible to achieve without running 2 instances of the same adapter (one with WS_ENABLED=true)? May be is just good practice having 2 instances?

Triggering the shouldNotServeInputUsingWS via a function that returns a boolean per endpoint in makeWSHandler did not work. The only thing that worked was switching on/off the wsConfig.enabled but it felt hacky cause the code snippet was placed in the endpointSelector

Thanks!

boxhock commented 2 years ago

This is something we have been discussing internally. TL;DR: Right now you'll have to deploy a separate WS-enabled adapter in addition to your non-WS adapter.

In the future, we would like to make it possible to do something like specifying the protocol to use in the request to the EA, which would allow you to run a single EA.

If you're able to make code changes, adding shouldNotServeInputUsingWS() should allow you to disable WS for that request. As long as this returns true, it should just discard the attempt to use WS even if WS is enabled on the EA.

vnavascues commented 2 years ago

Interesting cause as I said above, triggering the shouldNotServeInputUsingWS() did not work. This is the method that returns true for non-ws coinmetrics endpoints and calls the expected execute():

      shouldNotServeInputUsingWS: (input) => {
        const noWsEndpoints = endpoints.totalBurned.supportedEndpoints.concat(
          endpoints.burned.supportedEndpoints,
        )
        return noWsEndpoints.includes(input.data?.endpoint)
      },

According the response message it defaults to price endpoint (i.e. Required parameter base...) instead of hitting total-burned or burned.

Thanks for the explanation