API and go_core_query
The GoCore system provides two main ways to interact with the API: via standard HTTP(s) requests and through a persistent socket connection using the specialized go_core_query library.
API. Access via http(s)
Authorization
To work with the API, you must first perform an authorization request (User.login). In response, the server returns a JWT token, which must be passed in the Authorization header for all subsequent requests:
Authorization: Bearer <Token>
If the session is expired or invalidated, the server will return a standard response object (IAPIResponse) with code -4.
For more details, see the Caching System and Documentation sections.
Request Format
All API requests (including data retrieval) are sent using the POST method. This allows hiding request parameters from attackers and providers.
The request URL is constructed according to the template: /api/v1/:className/:command
- className: the name of the class (can be specified in lowercase).
- command: the name of the method being called.
Example (User.login):
URL: /api/v1/user/login
Request body: A JSON object with parameters (e.g., login and password).
curl Example:
curl -X 'POST' \
'http://127.0.0.1:7011/api/v1/user/login' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"password": "qwerty",
"login": "admin"
}'
Automatic Documentation
Documentation for API methods is generated automatically based on decorators in the code.
- Try methods interactively:
/api-docs - Download OpenAPI specification:
/api-docs/download
Access via Socket
Independent Connection
The connection uses the socket.io library (current version at the time of writing is 4.6.1). While an independent connection is possible, it involves a number of nuances. In most cases, it is recommended to use the ready-made go_core_query library.
go_core_query Library
This is a specialized library for working with GoCore via sockets. It is available via npm:
npm i go_core_query
The frontend built into the core uses this library.
Key Features
- Automatic transmission of client data (e.g., time zone).
- Token management and storage.
- Automatic authorization and re-authorization when a session is lost (relevant for connections from another service (backend-to-backend)).
- Connection state tracking and automatic reconnections with configured timings.
- Handling server requests for user redirection (e.g., to the login page).
- Convenient interface for sending requests to the API (similar to
fetch). - Request logging to the console (in debug mode).
The library supports various environments: browser (including older versions via <script>), Node.js, React Native.
Usage and Initialization
The main entry point is the initGoCoreQuery function. It returns an object with two fields:
- api: an asynchronous function for executing requests. It accepts
IAPIQueryand returnsPromise<IAPIResponse>. - instance: an instance of the
Queryclass, through which you can access the socket itself and other internal properties.
To subscribe to socket events, the afterInitConnect: (socket: Socket) => void parameter is typically used.
Connection Example (React)
Below is an example of an API interaction module implementation in a React application:
// @ts-ignore
import initGoCoreQuery from "go_core_query";
import { Socket } from "socket.io-client";
import { IAPIResponse } from "./structure";
export let api: (o: Record<string, any>) => Promise<IAPIResponse> = async (o) => {
console.log("GoCoreContextAPIFn is not ready now. Request will be repeated after short pause");
await new Promise<void>(cb => setTimeout(cb, 500));
return await api(o);
};
export let goCoreQueryInstance = {};
// ... (stub handlers for emit, socketOn, socketOff)
export const initGoCoreAPI = async (params: Record<string, any> = {}) => {
const { afterInitConnect, setIsAuth, socketOnConnect, socketOnDisconnect, socketOnError } = params;
// Setting Debug mode via cookies
let debugCookie = document.cookie.match(/debugGoCoreAPI=(\w+)/);
let debug = debugCookie ? debugCookie[1] === "true" : false;
const config = {
host: import.meta.env.VITE_APP_HOST,
port: import.meta.env.VITE_APP_PORT,
https: import.meta.env.VITE_APP_HTTPS === "true",
login: import.meta.env.VITE_APP_LOGIN,
password: import.meta.env.VITE_APP_PASSWORD,
autoAuth: import.meta.env.VITE_APP_AUTO_AUTH === "true",
useAJAX: false,
tokenStorageKey: "ProjectToken",
debug,
authFn: (_obj: any, cb: Function) => {
if (typeof setIsAuth === "function") {
setIsAuth(false);
if (typeof cb === "function") cb(null);
}
},
afterInitConnect: (socket: Socket) => {
if (typeof afterInitConnect === "function") afterInitConnect(socket);
socket.on("connect", () => {
if (typeof socketOnConnect === "function") socketOnConnect(socket);
// Overriding stub functions with real socket methods
// api = socketQueryOriginal.api;
});
socket.on("disconnect", () => {
if (typeof socketOnDisconnect === "function") socketOnDisconnect(socket);
});
},
};
const socketQueryOriginal = initGoCoreQuery(config);
api = socketQueryOriginal.api;
goCoreQueryInstance = socketQueryOriginal.instance;
};
Main Connection Parameters
- host, port, https: Server parameters. Important: specifying the wrong protocol (https) may result in no clear errors when connection fails.
- autoAuth: If
true, the library will automatically perform authorization (typically used for server-side connections). For frontend,falseis recommended. - authFn: Callback called when authorization is needed (e.g., redirect to
/login). - useAJAX: Allows the library to work via
fetchinstead of sockets. - tokenStorageKey: Key for storing the token in LocalStorage.
- debug, debugFull: Logging modes.
debugFulloutputs detailed information about the library’s internal states.
Calling Methods from the Console
In the interface built into the core, the api is available as a global variable, and therefore it can be used directly from the browser console (DevTools). To ensure the request is authorized, first log in through the interface. Then, the authorization header will be automatically attached when the socket connection is established. Usage Example:
api({
command: 'getMe',
object: 'User'
})