Flecs: Flecs Remote API
Description: A fast entity component system (ECS) for C & C++

| Flecs v4.1 A fast entity component system (ECS) for C & C++

Loading...
Searching...
No Matches
Flecs Remote API

The Flecs Remote API makes it possible to remotely interface with a Flecs application. Possible applications of the Flecs Remote API are:

- Remote tooling such as the Flecs Explorer
- Web applications that use Flecs as a backend store
- Web applications that connect to a Flecs wasm image
- Saving (and loading) ECS data to a file
- Saving (and loading) ECS data to a database

The Flecs Remote API consists out of these components:

- A JSON serializer/deserializer
- A REST API
- A client-side JavaScript library that wraps around the REST API
- The Flecs Explorer

# Explorer Quickstart

The most common usage of the Flecs Remote API is the Flecs Explorer. To allow the Flecs explorer to access an application, add this code:

- C

  // Optional, gather statistics for explorer
  ECS_IMPORT(world, FlecsStats);
  // Creates REST server on default port (27750)
  ecs_singleton_set(world, EcsRest, {0});
  // Runs the system serving up REST requests
  while (ecs_progress(world, 0)) { }
  ECS_IMPORT
  #define ECS_IMPORT(world, id)
  Wrapper around ecs_import().
  Definition module.h:125
  ecs_progress
  FLECS_API bool ecs_progress(ecs_world_t *world, ecs_ftime_t delta_time)
  Progress a world.
  ecs_singleton_set
  #define ecs_singleton_set(world, comp,...)
  Set a singleton component value.
  Definition flecs_c.h:507
  EcsRest
  Component that creates a REST API server when instantiated.
  Definition rest.h:59

- C++

  // Optional, gather statistics for explorer
  world.import<flecs::stats>();
  // Creates REST server on default port (27750)
  world.set<flecs::Rest>({});
  // Runs the system serving up REST requests
  while (world.progress()) { }
  flecs::Rest
  EcsRest Rest
  REST API component.
  Definition decl.hpp:19
  flecs::stats
  Stats module.
  Definition decl.hpp:28

- C#

  // Optional, gather statistics for explorer
  world.Import<Ecs.Stats>();
  // Creates REST server on default port (27750)
  world.Set<flecs.EcsRest>(default);
  // Runs the system serving up REST requests
  while (world.Progress()) { }

- Rust

  // Optional, gather statistics for explorer
  world.import::<stats::Stats>();
  // Creates REST server on default port (27750)
  world.set(flecs::rest::Rest::default());
  // Runs the system serving up REST requests
  while world.progress() {}

or, using the app addon:

- C

  ecs_world_t *world = ecs_init();
  ecs_app_run(world, &(ecs_app_desc_t) {
  // Optional, gather statistics for explorer
  .enable_stats = true
  .enable_rest = true,
  });
  ecs_app_run
  FLECS_API int ecs_app_run(ecs_world_t *world, ecs_app_desc_t *desc)
  Run application.
  ecs_world_t
  struct ecs_world_t ecs_world_t
  A world is the container for all ECS data and supporting features.
  Definition flecs.h:425
  ecs_init
  ecs_world_t * ecs_init(void)
  Create a new world.
  ecs_app_desc_t
  Used with ecs_app_run().
  Definition app.h:37

- C++

  world.app()
  // Optional, gather statistics for explorer
  .enable_stats()
  .enable_rest()
  .run();

- C#

  world.App()
  // Optional, gather statistics for explorer
  .EnableStats()
  .EnableRest()
  .Run();

- Rust

  world
  .app()
  // Optional, gather statistics for explorer
  .enable_stats(true)
  .enable_rest(0)
  .run();

When the application is running, navigate to this URL: https://flecs.dev/explorer . The explorer should connect automatically to the application.

# Usage

The following sections describe how the Flecs Remote API can be used by applications.

## JSON serialization

The Flecs JSON addon provides an easy API for serializing the world, queries and entities to JSON. The following example shows how to serialize the world to JSON:

- C

  ecs_world_t *world = ecs_init();
  char *json = ecs_world_to_json(world, NULL);
  if (!json) {
  // error
  }
  ecs_world_to_json
  FLECS_API char * ecs_world_to_json(ecs_world_t *world, const ecs_world_to_json_desc_t *desc)
  Serialize world into JSON string.

- C++

  flecs::world world;
  char *json = world.to_json();
  if (!json) {
  // error
  }
  flecs::world::to_json
  flecs::string to_json(flecs::entity_t tid, const void *value) const
  Serialize an untyped value to JSON.
  Definition world.hpp:12
  flecs::world
  The world.
  Definition world.hpp:246

The resulting JSON can be deserialized back into the world:

- C

  int res = ecs_world_from_json(world, json, NULL);
  if (res) {
  // error
  }
  ecs_world_from_json
  FLECS_API const char * ecs_world_from_json(ecs_world_t *world, const char *json, const ecs_from_json_desc_t *desc)
  Parse JSON object with multiple entities into the world.

- C++

  int res = world.from_json(json);
  if (res) {
  // error
  }
  flecs::world::from_json
  const char * from_json(flecs::entity_t tid, void *value, const char *json, flecs::from_json_desc_t *desc=nullptr)
  Deserialize a value from JSON.
  Definition world.hpp:42

Similarly, entities can be serialized to and from JSON:

- C

  ecs_entity_t e = ecs_insert(...);
  char *json = ecs_entity_to_json(world, e, NULL);
  if (!json) {
  // error
  }
  int res = ecs_entity_from_json(world, e, json, NULL);
  if (res) {
  // error
  }
  ecs_entity_from_json
  FLECS_API const char * ecs_entity_from_json(ecs_world_t *world, ecs_entity_t entity, const char *json, const ecs_from_json_desc_t *desc)
  Parse JSON object with multiple component values into an entity.
  ecs_entity_to_json
  FLECS_API char * ecs_entity_to_json(ecs_world_t *world, ecs_entity_t entity, const ecs_entity_to_json_desc_t *desc)
  Serialize entity into JSON string.
  ecs_entity_t
  ecs_id_t ecs_entity_t
  An entity identifier.
  Definition flecs.h:381
  ecs_insert
  #define ecs_insert(world,...)
  Insert a new entity with a list of component values.
  Definition flecs_c.h:349

- C++

  flecs::entity e = world.entity().set(...);
  char *json = e.to_json();
  if (!json) {
  // error
  }
  int res = e.from_json(json);
  if (res) {
  // error
  }
  flecs::entity_view::to_json
  flecs::string to_json(const flecs::entity_to_json_desc_t *desc=nullptr) const
  Serialize an entity to JSON.
  Definition entity_view.hpp:12
  flecs::entity::from_json
  const char * from_json(const char *json)
  Deserialize an entity from JSON.
  Definition entity.hpp:12
  flecs::world::entity
  flecs::entity entity(Args &&... args) const
  Create an entity.
  Definition impl.hpp:190
  flecs::entity_builder::set
  const Self & set(T &&value) const
  Set a component for an entity.
  Definition builder.hpp:705
  flecs::entity
  Entity.
  Definition entity.hpp:30

Queries can also be serialized to JSON:

- C

  ecs_query_t *q = ecs_query(world, {
  .expr = "Position, Velocity"
  });
  ecs_iter_t it = ecs_query_iter(world, q);
  char *json = ecs_iter_to_json(it, NULL);
  if (!json) {
  // error
  }
  ecs_iter_to_json
  FLECS_API char * ecs_iter_to_json(ecs_iter_t *iter, const ecs_iter_to_json_desc_t *desc)
  Serialize iterator into JSON string.
  ecs_query
  #define ecs_query(world,...)
  Shorthand for creating a query with ecs_query_init().
  Definition flecs_c.h:262
  ecs_query_iter
  ecs_iter_t ecs_query_iter(const ecs_world_t *world, const ecs_query_t *query)
  Create a query iterator.
  ecs_iter_t
  Iterator.
  Definition flecs.h:1166
  ecs_query_t
  Queries are lists of constraints (terms) that match entities.
  Definition flecs.h:834

- C++

  auto q = world.query<Position, Velocity>();
  char *json = q.to_json();
  if (!json) {
  // error
  }
  flecs::world::query
  flecs::query< Comps... > query(Args &&... args) const
  Create a query.
  Definition impl.hpp:271

For more details on the JSON format and the various serialization options, see the Remote API reference.

## REST API

The Flecs REST API enables remote access to running Flecs applications. The REST API can be used in various different ways:

- Using the embedded HTTP server
- Using a 3rd party HTTP server
- By calling ecs_http_server_request directly
- To communicate with a WASM image

The embedded HTTP server is a minimal implementation that only provides enough features to be able to serve up the REST API. It is sufficient for development purposes, but should not be used in production environments.

The Flecs REST API can be used in production environments to use Flecs as a backend datastore that can be dynamically queried. This requires forwarding requests to a 3rd party HTTP library (such as civetweb) using the ecs_http_server_request function.

The REST API can also be used to communicate with wasm images. By default when Flecs is built with emscripten, a function called flecs_explorer_request is exported as public symbol which enables doing REST requests. This symbol is used by the explorer to communicate with Flecs wasm images.

The following examples show how to enable the embedded REST API, which is required for using Flecs with the explorer:

- C

  // Optional, gather statistics for explorer
  ECS_IMPORT(world, FlecsStats);
  // Creates REST server on default port (27750)
  ecs_singleton_set(world, EcsRest, {0});
  // Runs the system serving up REST requests
  while (ecs_progress(world, 0)) { }

- C++

  // Optional, gather statistics for explorer
  world.import<flecs::stats>();
  // Creates REST server on default port (27750)
  world.set<flecs::Rest>({});
  // Runs the system serving up REST requests
  while (world.progress()) { }
  flecs::world::import
  flecs::entity import()
  Import a module.
  Definition impl.hpp:107
  flecs::world::progress
  bool progress(ecs_ftime_t delta_time=0.0) const
  Progress the world one tick.
  Definition impl.hpp:47
  flecs::world::set
  void set(const T &value) const
  Set singleton component.
  Definition world.hpp:784

- C#

  // Optional, gather statistics for explorer
  world.Import<Ecs.Stats>();
  // Creates REST server on default port (27750)
  world.Set<flecs.EcsRest>(default);
  // Runs the system serving up REST requests
  while (world.Progress()) { }

- Rust

  // Optional, gather statistics for explorer
  world.import::<stats::Stats>();
  // Creates REST server on default port (27750)
  world.set(flecs::rest::Rest::default());
  // Runs the system serving up REST requests
  while world.progress() {}

Alternatively applications can also use the app addon to enable and run the REST API, which provides a portable way to run applications across desktop, mobile and web applications:

- C

  ecs_world_t *world = ecs_init();
  ecs_app_run(world, &(ecs_app_desc_t) {
  // Optional, gather statistics for explorer
  .enable_stats = true
  .enable_rest = true,
  });

- C++

  world.app()
  // Optional, gather statistics for explorer
  .enable_stats()
  .enable_rest()
  .run();
  flecs::world::app
  flecs::app_builder app()
  Return an app builder.
  Definition world.hpp:20
  flecs::app_builder::run
  int run()
  Run the application.
  Definition builder.hpp:82
  flecs::app_builder::enable_stats
  app_builder & enable_stats(bool value=true)
  Enable statistics collection.
  Definition builder.hpp:64
  flecs::app_builder::enable_rest
  app_builder & enable_rest(uint16_t port=0)
  Enable the REST API.
  Definition builder.hpp:57

Alternatively the REST API can be called directly with the ecs_http_server_request C function. This makes it easy to use the REST API with a 3rd party HTTP server, or to run the API over a different protocol.

The following example shows how to use the ecs_http_server_request function:

// Create a REST server. Don't specify connectivity
// parameters which ensures no HTTP server is created.
ecs_http_server_t *srv = ecs_rest_server_init(
world, NULL);
ecs_http_reply_t reply = ECS_HTTP_REPLY_INIT;
int res = ecs_http_server_request(srv,
"GET", "/entity/my_entity", &reply);
if (res || reply.code != 200) {
// error
}
char *body = ecs_strbuf_get(&reply.body);
// Use reply body
ecs_os_free(body);
// Free server
ecs_rest_server_fini(srv);
ECS_HTTP_REPLY_INIT
#define ECS_HTTP_REPLY_INIT
Default initializer for ecs_http_reply_t.
Definition http.h:100
ecs_http_server_t
struct ecs_http_server_t ecs_http_server_t
HTTP server.
Definition http.h:48
ecs_http_server_request
FLECS_API int ecs_http_server_request(ecs_http_server_t *srv, const char *method, const char *req, const char *body, ecs_http_reply_t *reply_out)
Convenience wrapper around ecs_http_server_http_request().
ecs_rest_server_init
FLECS_API ecs_http_server_t * ecs_rest_server_init(ecs_world_t *world, const ecs_http_server_desc_t *desc)
Create HTTP server for REST API.
ecs_rest_server_fini
FLECS_API void ecs_rest_server_fini(ecs_http_server_t *srv)
Clean up REST HTTP server.
ecs_http_reply_t
An HTTP reply.
Definition http.h:91
ecs_http_reply_t::code
int code
default = 200.
Definition http.h:92
ecs_http_reply_t::body
ecs_strbuf_t body
default = "".
Definition http.h:93

For more details on the REST API, see the API reference.

# JavaScript library

The JavaScript library is a client-side wrapper that makes it easy to build web applications with the Flecs REST API. To use the client library, include it like this:

<script src="flecs.js" type="text/javascript" charset="utf-8"></script>

The latest version of the client library can be downloaded on this URL: https://www.flecs.dev/explorer/flecs.js

The client can then create a connection to a running application like this:

// Connect to localhost on the default port (27750)
let conn = flecs.connect("localhost");

Clients can also connect to a remote host:

let conn = flecs.connect("https://my-game.com/api:9000");

Clients can also connect directly to a wasm image:

let conn = flecs.connect("my-game.wasm");

Once the connection is created, the client can make requests:

conn.query("Position, Velocity, (ChildOf, scene)",
{}, (reply) => {
for (let entity of reply.results) {
console.log(`entity ${entity.name} matched!`);
}
});

# Reference

The following sections describe the different REST endpoints of the Flecs Remote API. Where applicable the corresponding JSON serialization code will be mentioned. The endpoint options map one to one to JSON (de)serializer options, prefixed by serialize_. For example, REST API option Values maps to JSON serializer option serialize_values.

## GET entity

Retrieve an entity and its tags, pairs and components.

GET entity/<path>

### Options

Option | Type | Description
--- | --- | ---
entity_id | bool | Serialize numeric entity id.
doc | bool | Serialize flecs doc components
full_paths | bool | Serialize full tag/pair/component paths
inherited | bool | Serialize inherited components
values | bool | Serialize component values
builtin | bool | Serialize builtin components for parent & name
type_info | bool | Serialize type info for components
matches | bool | Serialize matched with queries
alerts | bool | Serialize active alerts for entity & children
refs | entity | Serialize relationship back references
try | bool | Don't throw HTTP error on failure (REST only)

### Examples

In this example, Mass is a component with reflection data, Position is a pair component without reflection data, and (Description, Color) is a pair component with reflection data.

- HTTP

  GET /entity/Sun/Earth

- JavaScript

  const conn = flecs.connect("localhost");
  conn.entity("Sun.Earth", {}, (reply) => {
  // ...
  });

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  char *json = ecs_entity_to_json(world, e, NULL);
  // ...
  ecs_os_free(json);
  ecs_lookup
  ecs_entity_t ecs_lookup(const ecs_world_t *world, const char *path)
  Look up an entity by its path.

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  auto json = e.to_json();
  // ...
  flecs::world::lookup
  flecs::entity lookup(const char *name, const char *sep="::", const char *root_sep="::", bool recursive=true) const
  Lookup entity by name.
  Definition world.hpp:102

{
"parent": "Sun",
"name": "Earth",
"tags": [
"Planet"
],
"components": {
"Mass": {
"value": "5.9722e24"
},
"Position": null,
"(flecs.doc.Description,flecs.doc.Color)": {
"value": "#6b93d6"
}
}
}

This example shows how type_info can be used to obtain the component schema's. If no schema is available a null placeholder is sent. Note how the member name used in the type_info object is the same as used in the Components object. The example also shows the entity_id option, which adds the id member.

- HTTP

  GET /entity/Sun/Earth?id=true&type_info=true

- JavaScript

  const conn = flecs.connect("localhost");
  conn.entity("Sun.Earth", {id: true, type_info: true}, (reply) => {
  // ...
  });

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_entity_to_json_desc_t desc = ECS_ENTITY_TO_JSON_INIT;
  desc.serialize_entity_id = true;
  desc.serialize_type_info = true;
  char *json = ecs_entity_to_json(world, e, &desc);
  // ...
  ecs_os_free(json);
  ECS_ENTITY_TO_JSON_INIT
  #define ECS_ENTITY_TO_JSON_INIT
  Utility used to initialize JSON entity serializer.
  Definition json.h:238
  ecs_entity_to_json_desc_t
  Used with ecs_entity_to_json().
  Definition json.h:220
  ecs_entity_to_json_desc_t::serialize_type_info
  bool serialize_type_info
  Serialize type info (requires serialize_values).
  Definition json.h:227
  ecs_entity_to_json_desc_t::serialize_entity_id
  bool serialize_entity_id
  Serialize entity ID.
  Definition json.h:221

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  ecs_entity_to_json_desc_t desc = ECS_ENTITY_TO_JSON_INIT;
  desc.serialize_entity_id = true;
  desc.serialize_type_info = true;
  auto json = e.to_json(&desc);

{
"parent": "Sun",
"name": "Earth",
"id": 775,
"type_info": {
"Mass": {
"value": [
"float",
{
"unit": "flecs.units.Mass.KiloGrams",
"symbol": "kg",
"quantity": "flecs.units.Mass"
}
]
},
"Position": 0,
"(flecs.doc.Description,flecs.doc.Color)": {
"value": [
"text"
]
}
},
"tags": [
"Planet"
],
"components": {
"Mass": {
"value": "5.9722e24"
},
"Position": null,
"(flecs.doc.Description,flecs.doc.Color)": {
"value": "#6b93d6"
}
}
}

This example demonstrates serializing inherited tags, pairs and components. Prefabs are added in the order they are encountered when traversing the IsA relationship. If multiple prefabs have the same component, the component will show up multiple times in the reply. A client must only consider the first occurrence of the component.

- HTTP

  GET /entity/Sun/Earth?inherited=true

- JavaScript

  const conn = flecs.connect("localhost");
  conn.entity("Sun.Earth", {inherited: true}, (reply) => {
  // ...
  });

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_entity_to_json_desc_t desc = ECS_ENTITY_TO_JSON_INIT;
  desc.serialize_inherited = true;
  char *json = ecs_entity_to_json(world, e, &desc);
  // ...
  ecs_os_free(json);
  ecs_entity_to_json_desc_t::serialize_inherited
  bool serialize_inherited
  Serialize base components.
  Definition json.h:224

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  ecs_entity_to_json_desc_t desc = ECS_ENTITY_TO_JSON_INIT;
  desc.serialize_inherited = true;
  auto json = e.to_json(&desc);

{
"parent": "Sun",
"name": "Earth",
"tags": [
"Planet"
],
"pairs": {
"flecs.core.IsA": "HabitablePlanet"
},
"inherited": {
"planets.HabitablePlanet": {
"tags": [
"HasWater",
"HasBreathableAir"
]
}
},
"components": {
"Mass": {
"value": "5.9722e24"
}
}
}

The following example shows the effect of disabling serialization of component values.

- HTTP

  GET /entity/Sun/Earth?values=false

- JavaScript

  const conn = flecs.connect("localhost");
  conn.entity("Sun.Earth", {values: false}, (reply) => {
  // ...
  });

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_entity_to_json_desc_t desc = ECS_ENTITY_TO_JSON_INIT;
  desc.serialize_values = false;
  char *json = ecs_entity_to_json(world, e, &desc);
  // ...
  ecs_os_free(json);
  ecs_entity_to_json_desc_t::serialize_values
  bool serialize_values
  Serialize component values.
  Definition json.h:225

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  ecs_entity_to_json_desc_t desc = ECS_ENTITY_TO_JSON_INIT;
  desc.serialize_values = false;
  auto json = e.to_json(&desc);

{
"parent": "Sun",
"name": "Earth",
"tags": [
"Planet"
],
"components": {
"Mass": null,
}
}

## PUT entity

Create an entity.

PUT /entity/<path>

### Examples

The following example creates entity Sun.Earth.

- HTTP

  PUT /entity/Sun/Earth

- JavaScript

  const conn = flecs.connect("localhost");
  conn.create("Sun.Earth");

- C

  ecs_entity_t e = ecs_entity(world, { .name = "Sun.Earth" });
  ecs_entity
  #define ecs_entity(world,...)
  Shorthand for creating an entity with ecs_entity_init().
  Definition flecs_c.h:235

- C++

  flecs::entity e = world.entity("Sun.Earth");

## DELETE entity

Delete an entity.

DELETE /entity/<path>

### Examples

The following example deletes entity Sun.Earth.

- HTTP

  DELETE /entity/Sun/Earth

- JavaScript

  const conn = flecs.connect("localhost");
  conn.delete("Sun.Earth");

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_delete(world, e);
  ecs_delete
  void ecs_delete(ecs_world_t *world, ecs_entity_t entity)
  Delete an entity.

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  e.destruct();
  flecs::entity::destruct
  void destruct() const
  Delete an entity.
  Definition entity.hpp:416

## GET component

Retrieve a single component from an entity.

GET /component/<path>?component=<component>

### Examples

- HTTP

  GET /component/Sun/Earth?component=planets.Mass

- JavaScript

  const conn = flecs.connect("localhost");
  conn.get("Sun.Earth", {component: "planets.Mass"}, (reply) => {
  // ...
  });

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_entity_t c = ecs_lookup(world, "planets.Mass");
  const void *ptr = ecs_get_id(world, e, c);
  char *json = ecs_ptr_to_json(world, c, ptr);
  // ...
  ecs_os_free(json);
  ecs_ptr_to_json
  FLECS_API char * ecs_ptr_to_json(const ecs_world_t *world, ecs_entity_t type, const void *data)
  Serialize value into JSON string.
  ecs_get_id
  const void * ecs_get_id(const ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
  Get an immutable pointer to a component.

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  flecs::entity c = world.lookup("planets::Mass");
  const void *ptr = e.get(c);
  auto json = world.to_json(c, ptr);
  flecs::entity_view::get
  const T & get() const
  Get component value.
  Definition entity_view.hpp:432

{ "value": "5.9722e24" }

## PUT component

Add or set a component.

PUT /component/<path>?component=<component>[&value=<value>]

### Examples

The following example adds the component Position to Sun.Earth:

- HTTP

  PUT /component/Sun/Earth?component=Position

- JavaScript

  const conn = flecs.connect("localhost");
  conn.add("Sun.Earth", "Position");

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_entity_t c = ecs_lookup(world, "Position");
  ecs_add_id(world, e, c);
  ecs_add_id
  void ecs_add_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
  Add a (component) ID to an entity.

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  flecs::entity c = world.lookup("planets::Mass");
  e.add(c);
  flecs::entity_builder::add
  const Self & add() const
  Add a component to an entity.
  Definition builder.hpp:25

The following example writes the value {"x":10} to the Position component of entity Sun.Earth:

- HTTP

  PUT /component/Sun/Earth?component=Position&value=%7B%22x%22%3A%2210%22%7D

- JavaScript

  const conn = flecs.connect("localhost");
  conn.set("Sun.Earth", "Position", {x: 10});

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_entity_t c = ecs_lookup(world, "Position");
  void *ptr = ecs_get_mut_id(world, e, c);
  ecs_ptr_from_json(world, c, ptr, "{\"x\": 10}", NULL);
  ecs_ptr_from_json
  FLECS_API const char * ecs_ptr_from_json(const ecs_world_t *world, ecs_entity_t type, void *ptr, const char *json, const ecs_from_json_desc_t *desc)
  Parse JSON string into value.
  ecs_get_mut_id
  void * ecs_get_mut_id(const ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
  Get a mutable pointer to a component.

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  flecs::entity c = world.lookup("planets::Mass");
  void *ptr = e.get_mut(c);
  world.from_json(c, ptr, "{\"x\": 10}");
  flecs::entity_view::get_mut
  T & get_mut() const
  Get mutable component value.
  Definition entity_view.hpp:772

## DELETE component

Remove a component from an entity.

DELETE /component/<path>?component=<component>

### Examples

The following example removes the component Position from Sun.Earth:

- HTTP

  DELETE /component/Sun/Earth?component=Position

- JavaScript

  const conn = flecs.connect("localhost");
  conn.remove("Sun.Earth", "Position");

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_entity_t c = ecs_lookup(world, "Position");
  ecs_remove_id(world, e, c);
  ecs_remove_id
  void ecs_remove_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
  Remove a component from an entity.

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  flecs::entity c = world.lookup("planets::Mass");
  e.remove(c);
  flecs::entity_builder::remove
  const Self & remove() const
  Remove a component from an entity.
  Definition builder.hpp:303

## PUT toggle

Toggle an entity or component.

PUT /toggle/<path>?enable=[true|false][&component=<component>]

When an entity is toggled, the Disabled tag is added or removed. When a component is toggled, the ecs_enable_id operation is invoked. A component toggle request will fail if the component does not have the CanToggle trait.

### Examples

The following example disables entity Sun.Earth:

- HTTP

  PUT /toggle/Sun/Earth?enable=false

- JavaScript

  const conn = flecs.connect("localhost");
  conn.disable("Sun.Earth");

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_enable(world, e, false);
  ecs_enable
  void ecs_enable(ecs_world_t *world, ecs_entity_t entity, bool enabled)
  Enable or disable an entity.

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  e.disable();
  flecs::entity_builder::disable
  const Self & disable() const
  Disable an entity.
  Definition builder.hpp:566

The following example disables component Position for entity Sun.Earth:

- HTTP

  PUT /toggle/Sun/Earth?enable=false&component=Position

- JavaScript

  const conn = flecs.connect("localhost");
  conn.disable("Sun.Earth", "Position");

- C

  ecs_entity_t e = ecs_lookup(world, "Sun.Earth");
  ecs_entity_t c = ecs_lookup(world, "Position");
  ecs_enable_id(world, e, c, false);
  ecs_enable_id
  void ecs_enable_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component, bool enable)
  Enable or disable a component.

- C++

  flecs::entity e = world.lookup("Sun::Earth");
  flecs::entity c = world.lookup("Position");
  e.disable(c);

## GET query

Retrieve matching results for a query.

GET /query/?expr=<query expression>

### Options

Option | Type | Description
--- | --- | ---
name | string | Evaluate existing named query.
expr | string | Evaluate query expression.
entity_id | bool | Serialize numeric entity id.
doc | bool | Serialize flecs doc components
full_paths | bool | Serialize full tag/pair/component paths
inherited | bool | Serialize inherited components
values | bool | Serialize component values
builtin | bool | Serialize builtin components for parent & name
fields | bool | Serialize query fields
table | bool | Serialize table (all components for match)
result | bool | Serialize results (disable for metadata-only request)
type_info | bool | Serialize type info for components
field_info | bool | Serialize field info
query_info | bool | Serialize query info
query_plan | bool | Serialize query plan
query_profile | bool | Serialize query profiling information
try | bool | Don't throw HTTP error on failure (REST only)

### Examples

The following example returns the results for query Position, Velocity. Note how each of the query terms results in a field in the reply. The mapping between query terms and fields is the same as in the regular flecs API.

- HTTP

  GET /query?expr=Position%2CVelocity

- JavaScript

  const conn = flecs.connect("localhost");
  conn.query("Position, Velocity", {}, (reply) => {
  // ...
  });

- C

  ecs_query_t *q = ecs_query(world, {
  .expr = "Position, Velocity"
  });
  ecs_iter_t it = ecs_query_iter(world, q);
  char *json = ecs_iter_to_json(&it, NULL);
  // ...
  ecs_os_free(json);

- C++

  flecs::query<> q = world.query_builder()
  .expr("Position, Velocity")
  .build();
  auto json = q.iter().to_json();
  flecs::world::query_builder
  flecs::query_builder< Comps... > query_builder(Args &&... args) const
  Create a query builder.
  Definition impl.hpp:283
  flecs::iterable::iter
  iter_iterable< Components... > iter(flecs::world_t *world=nullptr) const
  Create an iterator.
  Definition iterable.hpp:294
  flecs::query
  Typed query.
  Definition impl.hpp:220

{
"results": [
{
"parent": "Earth.shipyard",
"name": "USS Enterprise",
"fields": {
"values": [
{
"x": 10,
"y": 20
},
{
"x": 1,
"y": 2
}
]
}
},
{
"parent": "Earth.shipyard",
"name": "USS Voyager",
"fields": {
"values": [
{
"x": 30,
"y": 40
},
{
"x": 3,
"y": 4
}
]
}
}
]
}

The following example shows the result of setting table to true, which serializes all components (the table) of each matched entity. The format of the individually returned results is the same as the /entity endpoint.

- HTTP

  GET /query?expr=Position%2CVelocity?table=true

- JavaScript

  const conn = flecs.connect("localhost");
  conn.query("Position, Velocity", {table: true}, (reply) => {
  // ...
  });

- C

  ecs_query_t *q = ecs_query(world, {
  .expr = "Position, Velocity"
  });
  ecs_iter_t it = ecs_query_iter(world, q);
  ecs_iter_to_json_t desc = ECS_ITER_TO_JSON_INIT;
  desc.serialize_table = true;
  char *json = ecs_iter_to_json(&it, &desc);
  // ...
  ecs_os_free(json);
  ECS_ITER_TO_JSON_INIT
  #define ECS_ITER_TO_JSON_INIT
  Utility used to initialize JSON iterator serializer.
  Definition json.h:329

- C++

  flecs::query<> q = world.query_builder()
  .expr("Position, Velocity")
  .build();
  ecs_iter_to_json_t desc = ECS_ITER_TO_JSON_INIT;
  desc.serialize_table = true;
  auto json = q.iter().to_json(&desc);

{
"results": [
{
"parent": "Earth.shipyard",
"name": "USS Enterprise",
"tags": [
"Broken",
"FtlEnabled"
],
"pairs": {
"flecs.core.IsA": "Freighter"
},
"components": {
"Position": {
"x": 10,
"y": 20
},
"Velocity": {
"x": 1,
"y": 1
}
}
},
{
"parent": "Earth.shipyard",
"name": "USS Voyager",
"tags": [
"FtlEnabled"
],
"pairs": {
"IsA": "Freighter"
},
"components": {
"Position": {
"x": 30,
"y": 40
},
"Velocity": {
"x": 3,
"y": 4
}
}
}
]
}

The following example shows the result for query Position, ?Position(up). This shows the information that gets added to the query result to describe what the source of a field is, and whether a field is set or not.

The is_set member is only added to the result if one of the fields in the result is not set. The sources member is only added to the result if one of the fields in the result is not matched on the $this query variable.

- HTTP

  GET /query?expr=Position%2C%3FPosition(up)

- JavaScript

  const conn = flecs.connect("localhost");
  conn.query("Position, ?Position(up)", {}, (reply) => {
  // ...
  });

- C

  ecs_query_t *q = ecs_query(world, {
  .expr = "Position, ?Position(up)"
  });
  ecs_iter_t it = ecs_query_iter(world, q);
  char *json = ecs_iter_to_json(&it, NULL);
  // ...
  ecs_os_free(json);

- C++

  flecs::query<> q = world.query_builder()
  .expr("Position, ?Position(up)")
  .build();
  auto json = q.iter().to_json();

{
"results": [
{
"name": "Earth.shipyard",
"fields": {
"is_set": [true, false],
"sources": [0, 0],
"values": [
{
"x": 100,
"y": 200
},
{}
]
}
},
{
"parent": "Earth.shipyard",
"name": "USS Voyager",
"fields": {
"sources": [0, "Earth.shipyard"],
"values": [
{
"x": 30,
"y": 40
},
{
"x": 3,
"y": 4
}
]
}
},
{
"parent": "Earth.shipyard",
"name": "USS Voyager",
"fields": {
"sources": [0, "Earth.shipyard"],
"values": [
{
"x": 30,
"y": 40
},
{
"x": 3,
"y": 4
}
]
}
}
]
}

The following example shows the same query (Position, ?Position(up)) with fields set to false and entity_ids set to true.

- HTTP

  GET /query?expr=Position%2C%3FPosition(up)&fields=false&entity_ids=true

- JavaScript

  const conn = flecs.connect("localhost");
  conn.query("Position, ?Position(up)", {fields: false, entity_ids: true}, (reply) => {
  // ...
  });

- C

  ecs_query_t *q = ecs_query(world, {
  .expr = "Position, ?Position(up)"
  });
  ecs_iter_t it = ecs_query_iter(world, q);
  ecs_iter_to_json_t desc = ECS_ITER_TO_JSON_INIT;
  desc.serialize_fields = true;
  desc.serialize_entity_ids = true;
  char *json = ecs_iter_to_json(&it, &desc);
  // ...
  ecs_os_free(json);

- C++

  flecs::query<> q = world.query_builder()
  .expr("Position, ?Position(up)")
  .build();
  ecs_iter_to_json_t desc = ECS_ITER_TO_JSON_INIT;
  desc.serialize_fields = true;
  desc.serialize_entity_ids = true;
  auto json = q.iter().to_json(&desc);

{
"results": [
{
"name": "Earth.shipyard",
"id": 700
},
{
"parent": "Earth.shipyard",
"name": "USS Voyager",
"id": 701
},
{
"parent": "Earth.shipyard",
"name": "USS Voyager",
"id": 702
}
]
}

The following example shows how variables are serialized with the query Position, (ChildOf, $p). The IDs member is added to the serialized data, as the second term of this query has a variable (pair) id. Only fields with variable component ids are serialized to the IDs array.

- HTTP

  GET /query?expr=Position%2C(ChildOf%2C%24p)

- JavaScript

  const conn = flecs.connect("localhost");
  conn.query("Position, (ChildOf, $p)", {}, (reply) => {
  // ...
  });

- C

  ecs_query_t *q = ecs_query(world, {
  .expr = "Position, (ChildOf, $p)"
  });
  ecs_iter_t it = ecs_query_iter(world, q);
  char *json = ecs_iter_to_json(&it, NULL);
  // ...
  ecs_os_free(json);

- C++

  flecs::query<> q = world.query_builder()
  .expr("Position, (ChildOf, $p)")
  .build();
  auto json = q.iter().to_json();

{
"results": [
{
"parent": "Earth",
"name": "shipyard",
"vars": {
"p": "Earth"
},
"fields": {
"ids": [0, ["flecs.core.ChildOf", "Earth"]],
"values": [
{
"x": 100,
"y": 200
},
0]
}
},
{
"parent": "Earth.shipyard",
"name": "USS Enterprise",
"vars": {
"p": "shipyard"
},
"fields": {
"ids": [0, ["flecs.core.ChildOf", "Earth.shipyard"]],
"values": [
{
"x": 10,
"y": 20
},
0]
}
},
{
"parent": "Earth.shipyard",
"name": "USS Voyager",
"vars": {
"p": "shipyard"
},
"fields": {
"ids": [0, ["flecs.core.ChildOf", "Earth.shipyard"]],
"values": [
{
"x": 10,
"y": 20
},
0]
}
}
]
}

The following example shows the result of setting query_info and field_info to true, and setting results to false. This can be used to obtain meta information about a query. query_info returns a result per term, whereas field_info returns a result per field. The query is Position, ?Mass(up).

- HTTP

  GET /query?expr=Position%2C%3FMass(up)?query_info=true&field_info=true&results=false

- JavaScript

  const conn = flecs.connect("localhost");
  conn.query("Position, ?Mass(up)", {
  query_info: true,
  field_info: true,
  results: false
  }, (reply) => {
  // ...
  });

- C

  ecs_query_t *q = ecs_query(world, {
  .expr = "Position, ?Mass(up)"
  });
  ecs_iter_t it = ecs_query_iter(world, q);
  ecs_iter_to_json_t desc = ECS_ITER_TO_JSON_INIT;
  desc.serialize_query_info = true;
  desc.serialize_field_info = true;
  desc.serialize_results = true;
  char *json = ecs_iter_to_json(&it, &desc);
  // ...
  ecs_os_free(json);

- C++

  flecs::query<> q = world.query_builder()
  .expr("Position, ?Mass(up)")
  .build();
  ecs_iter_to_json_t desc = ECS_ITER_TO_JSON_INIT;
  desc.serialize_query_info = true;
  desc.serialize_field_info = true;
  desc.serialize_results = true;
  auto json = q.iter().to_json(&desc);

{
"field_info": [
{
"id": "Position",
"type": "Position",
"symbol": "Position",
"schema": {
"x": [
"float"
],
"y": [
"float"
]
}
},
{
"id": "Mass",
"optional": true,
"type": "Mass",
"symbol": "Mass",
"schema": {
"value": [
"float"
]
}
}
],
"query_info": {
"vars": [
"this"
],
"terms": [
{
"inout": "default",
"has_value": true,
"oper": "and",
"src": {
"var": "this"
},
"first": {
"entity": "Position",
"symbol": "Position",
"type": true
},
"flags": [
"self"
]
},
{
"inout": "default",
"has_value": true,
"oper": "optional",
"src": {
"var": "this"
},
"first": {
"entity": "Mass",
"symbol": "Mass",
"type": true
},
"trav": {
"entity": "flecs.core.ChildOf",
"symbol": "EcsChildOf"
},
"flags": [
"up"
]
}
]
}
}

## GET world

Retrieve all serializable data in the world.

GET /world

### Example

- HTTP

  GET /world

- JavaScript

  const conn = flecs.connect("localhost");
  conn.world((reply) => {
  // ...
  });

- C

  char *json = ecs_world_to_json(NULL);
  // ...
  ecs_os_free(json);

- C++

  auto json = world.to_json();

The output of this endpoint is equivalent to requesting the following query on the query endpoint with table=true:

!ChildOf(self|up, flecs),
!Module(self|up),
?Prefab,
?Disabled

This excludes modules and builtin entities from the result, effectively just returning entities that are active in a scene.

## PUT script

Update code for Flecs script.

PUT /script/<path>?code=<code>

When the code failed to parse a response is sent back with the error:

{
"error": "58: unexpected end of script\n}\n ^"
}

### Example

- HTTP

  PUT /script/main.flecs?code=SpaceShip{}

- JavaScript

  const conn = flecs.connect("localhost");
  conn.scriptUpdate("main\\.flecs", "SpaceShip{}");

- C

  ecs_entity_t s = ecs_lookup(world, "main\\.flecs");
  ecs_script_update(world, s, 0, "SpaceShip{}");
  ecs_script_update
  FLECS_API int ecs_script_update(ecs_world_t *world, ecs_entity_t script, ecs_entity_t instance, const char *code)
  Update script with new code.

- C++

  flecs::entity s = world.lookup("main.flecs");
  ecs_script_update(world, s, 0, "SpaceShip{}");