GET /config
Server capabilities exposed to TradingView's Charting Library
/config advertises what the backend supports. TradingView's Charting Library calls this first when mounting a chart and uses the response to decide which UI features to enable (symbol search, server time sync, etc.).
- Method:
GET - Path:
/api/nepse/tradingview/config - Content-Type:
application/json - Query params: none
Response shape
{
"supported_resolutions": ["1", "5", "15", "30", "60", "1D", "1W", "1M"],
"supports_search": true,
"supports_group_request": false,
"supports_marks": false,
"supports_timescale_marks": false,
"supports_time": true,
"exchanges": [
{ "value": "NEPSE", "name": "NEPSE", "desc": "Nepal Stock Exchange" }
],
"symbols_types": [
{ "name": "All types", "value": "" },
{ "name": "Stock", "value": "stock" }
]
}| Field | Type | Value | Why |
|---|---|---|---|
supported_resolutions | string[] | ["1","5","15","30","60","1D","1W","1M"] | Five intraday minute-buckets plus daily/weekly/monthly. |
supports_search | boolean | true | /search endpoint is implemented. |
supports_group_request | boolean | false | We don't support batch symbol resolution. |
supports_marks | boolean | false | No events/marks layer. |
supports_timescale_marks | boolean | false | No timescale marks. |
supports_time | boolean | true | /time endpoint is implemented. The library uses it to stay clock-synced with the server, which matters for real-time bar rollover. |
exchanges | Exchange[] | NEPSE only | Single-exchange deployment. |
symbols_types | SymbolType[] | All types + Stock | NEPSE has only stock-type instruments in the UDF sense. |
The payload is emitted at the root — no {message, data} envelope. Flat supports_* booleans. The TradingView library parses these directly; an envelope breaks symbol resolution entirely.
Why /time and /search are advertised
TradingView gates UI features on the booleans in /config:
supports_time: true→ the library calls/timeperiodically and adjusts its internal clock.supports_search: true→ the symbol-search UI becomes active; it calls/search?query=…as the user types.
If either boolean is false, the corresponding feature is disabled in the chart regardless of whether the backend endpoint exists.
Performance
The response is a compile-time constant struct. The handler marshals it once per process using a sync.Once around a []byte, then writes that byte slice directly on every subsequent request — zero per-request allocation.
type configBytesCache struct {
once sync.Once
bytes []byte
err error
}
func (c *configBytesCache) get(cfg *ConfigResponse) ([]byte, error) {
c.once.Do(func() {
c.bytes, c.err = json.Marshal(cfg)
})
return c.bytes, c.err
}Three consecutive /config calls should return identical bytes (identical md5). Verify:
curl -s https://api.ranjanyadav.com.np/api/nepse/tradingview/config | md5sum
curl -s https://api.ranjanyadav.com.np/api/nepse/tradingview/config | md5sum
curl -s https://api.ranjanyadav.com.np/api/nepse/tradingview/config | md5sumBecause the payload is small and cacheable, Nginx is also configured to serve it with a 1-hour proxy_cache_valid.
Invalidation
The cached bytes live for the process lifetime — they're invalidated on deploy (the process restarts). There is no runtime invalidation hook, and there shouldn't need to be: changing the config implies changing the binary.
Errors
| Condition | Status | Body |
|---|---|---|
| Marshal failure (should be impossible — struct is static) | 500 | {"s":"error","errmsg":"internal_error"} |
| Panic inside handler | 500 | {"s":"error","errmsg":"internal_error"} (from tradingview.Recoverer()) |
Verification
# Must have supports_time:true at the root
curl -s "$BASE/config" | jq '.supports_time, .supports_search'
# true
# true
# Must NOT have envelope keys
curl -s "$BASE/config" | jq 'if has("data") or has("message") then "LEAK" else "ok" end'
# "ok"Implementation
- Handler:
internal/modules/nepse/tradingview/handler.go→(*Handler).Config - Service:
internal/modules/nepse/tradingview/service.go→(*Service).GetConfig - Cache:
internal/modules/nepse/tradingview/cache.go→configBytesCache - Type:
internal/modules/nepse/tradingview/types.go→ConfigResponse