Page Not Found
We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/404.html b/404.html new file mode 100644 index 00000000000..4b0638b6347 --- /dev/null +++ b/404.html @@ -0,0 +1,23 @@ + + +
+ + +We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
autoload
",id:"autoload",level:3},{value:"services
",id:"services",level:3},{value:"entrypoint
",id:"entrypoint",level:3},{value:"hotReload
",id:"hotreload",level:3},{value:"allowCycles
",id:"allowcycles",level:3},{value:"telemetry
",id:"telemetry",level:3},{value:"server
",id:"server",level:3},{value:"Environment variable placeholders",id:"environment-variable-placeholders",level:2},{value:"Setting environment variables",id:"setting-environment-variables",level:3},{value:"Allowed placeholder names",id:"allowed-placeholder-names",level:3}],m={toc:s},d="wrapper";function c(e){let{components:t,...n}=e;return(0,a.kt)(d,(0,i.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"configuration"},"Configuration"),(0,a.kt)("p",null,"Platformatic Runtime is configured with a configuration file. It supports the\nuse of environment variables as setting values with ",(0,a.kt)("a",{parentName:"p",href:"#configuration-placeholders"},"configuration placeholders"),"."),(0,a.kt)("h2",{id:"configuration-file"},"Configuration file"),(0,a.kt)("p",null,"If the Platformatic CLI finds a file in the current working directory matching\none of these filenames, it will automatically load it:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"platformatic.runtime.json")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"platformatic.runtime.json5")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"platformatic.runtime.yml")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"platformatic.runtime.yaml")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"platformatic.runtime.tml")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"platformatic.runtime.toml"))),(0,a.kt)("p",null,"Alternatively, a ",(0,a.kt)("a",{parentName:"p",href:"/docs/1.11.0/reference/cli#service"},(0,a.kt)("inlineCode",{parentName:"a"},"--config")," option")," with a configuration\nfilepath can be passed to most ",(0,a.kt)("inlineCode",{parentName:"p"},"platformatic runtime")," CLI commands."),(0,a.kt)("p",null,"The configuration examples in this reference use JSON."),(0,a.kt)("h3",{id:"supported-formats"},"Supported formats"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:"left"},"Format"),(0,a.kt)("th",{parentName:"tr",align:"left"},"Extensions"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"left"},"JSON"),(0,a.kt)("td",{parentName:"tr",align:"left"},(0,a.kt)("inlineCode",{parentName:"td"},".json"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"left"},"JSON5"),(0,a.kt)("td",{parentName:"tr",align:"left"},(0,a.kt)("inlineCode",{parentName:"td"},".json5"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"left"},"YAML"),(0,a.kt)("td",{parentName:"tr",align:"left"},(0,a.kt)("inlineCode",{parentName:"td"},".yml"),", ",(0,a.kt)("inlineCode",{parentName:"td"},".yaml"))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:"left"},"TOML"),(0,a.kt)("td",{parentName:"tr",align:"left"},(0,a.kt)("inlineCode",{parentName:"td"},".tml"))))),(0,a.kt)("p",null,"Comments are supported by the JSON5, YAML and TOML file formats."),(0,a.kt)("h2",{id:"settings"},"Settings"),(0,a.kt)("p",null,"Configuration settings are organized into the following groups:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#autoload"},(0,a.kt)("inlineCode",{parentName:"a"},"autoload"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#services"},(0,a.kt)("inlineCode",{parentName:"a"},"services"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#entrypoint"},(0,a.kt)("inlineCode",{parentName:"a"},"entrypoint"))," ",(0,a.kt)("strong",{parentName:"li"},"(required)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#hotReload"},(0,a.kt)("inlineCode",{parentName:"a"},"hotReload"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#allowCycles"},(0,a.kt)("inlineCode",{parentName:"a"},"allowCycles"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#telemetry"},(0,a.kt)("inlineCode",{parentName:"a"},"telemetry"))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#server"},(0,a.kt)("inlineCode",{parentName:"a"},"server")))),(0,a.kt)("p",null,"Configuration settings containing sensitive data should be set using\n",(0,a.kt)("a",{parentName:"p",href:"#configuration-placeholders"},"configuration placeholders"),"."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"autoload")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"services")," settings can be used together, but at least one\nof them must be provided. When the configuration file is parsed, ",(0,a.kt)("inlineCode",{parentName:"p"},"autoload"),"\nconfiguration is translated into ",(0,a.kt)("inlineCode",{parentName:"p"},"services")," configuration."),(0,a.kt)("h3",{id:"autoload"},(0,a.kt)("inlineCode",{parentName:"h3"},"autoload")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"autoload")," configuration is intended to be used with monorepo applications.\n",(0,a.kt)("inlineCode",{parentName:"p"},"autoload")," is an object with the following settings:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"path"))," (",(0,a.kt)("strong",{parentName:"li"},"required"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") - The path to a directory containing the\nmicroservices to load. In a traditional monorepo application, this directory is\ntypically named ",(0,a.kt)("inlineCode",{parentName:"li"},"packages"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"exclude"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"array")," of ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"s) - Child directories inside of ",(0,a.kt)("inlineCode",{parentName:"li"},"path")," that\nshould not be processed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"mappings"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"object"),") - Each microservice is given an ID and is expected\nto have a Platformatic configuration file. By default the ID is the\nmicroservice's directory name, and the configuration file is expected to be a\nwell-known Platformatic configuration file. ",(0,a.kt)("inlineCode",{parentName:"li"},"mappings")," can be used to override\nthese default values.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"id"))," (",(0,a.kt)("strong",{parentName:"li"},"required"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") - The overridden ID. This becomes the new\nmicroservice ID."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"config")," ("),"required**, ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") - The overridden configuration file\nname. This is the file that will be used when starting the microservice."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"useHttp"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"boolean"),") - The service will be started on a random HTTP port\non ",(0,a.kt)("inlineCode",{parentName:"li"},"127.0.0.1"),", and exposed to the other services via that port; set it to ",(0,a.kt)("inlineCode",{parentName:"li"},"true"),"\nif you are using ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/fastify/fastify-express"},"@fastify/express"),".\nDefault: ",(0,a.kt)("inlineCode",{parentName:"li"},"false"),".")))),(0,a.kt)("h3",{id:"services"},(0,a.kt)("inlineCode",{parentName:"h3"},"services")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"services")," is an array of objects that defines the microservices managed by the\nruntime. Each service object supports the following settings:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"id"))," (",(0,a.kt)("strong",{parentName:"li"},"required"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") - A unique identifier for the microservice.\nWhen working with the Platformatic Composer, this value corresponds to the ",(0,a.kt)("inlineCode",{parentName:"li"},"id"),"\nproperty of each object in the ",(0,a.kt)("inlineCode",{parentName:"li"},"services")," section of the config file. When\nworking with client objects, this corresponds to the optional ",(0,a.kt)("inlineCode",{parentName:"li"},"serviceId"),"\nproperty or the ",(0,a.kt)("inlineCode",{parentName:"li"},"name")," field in the client's ",(0,a.kt)("inlineCode",{parentName:"li"},"package.json")," file if a\n",(0,a.kt)("inlineCode",{parentName:"li"},"serviceId")," is not explicitly provided."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"path"))," (",(0,a.kt)("strong",{parentName:"li"},"required"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") - The path to the directory containing\nthe microservice."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"config"))," (",(0,a.kt)("strong",{parentName:"li"},"required"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") - The configuration file used to start\nthe microservice."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"useHttp"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"boolean"),") - The service will be started on a random HTTP port\non ",(0,a.kt)("inlineCode",{parentName:"li"},"127.0.0.1"),", and exposed to the other services via that port; set it to ",(0,a.kt)("inlineCode",{parentName:"li"},"true"),"\nif you are using ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/fastify/fastify-express"},"@fastify/express"),".\nDefault: ",(0,a.kt)("inlineCode",{parentName:"li"},"false"),".")),(0,a.kt)("h3",{id:"entrypoint"},(0,a.kt)("inlineCode",{parentName:"h3"},"entrypoint")),(0,a.kt)("p",null,"The Platformatic Runtime's entrypoint is a microservice that is exposed\npublicly. This value must be the ID of a service defined via the ",(0,a.kt)("inlineCode",{parentName:"p"},"autoload")," or\n",(0,a.kt)("inlineCode",{parentName:"p"},"services")," configuration."),(0,a.kt)("h3",{id:"hotreload"},(0,a.kt)("inlineCode",{parentName:"h3"},"hotReload")),(0,a.kt)("p",null,"An optional boolean, defaulting to ",(0,a.kt)("inlineCode",{parentName:"p"},"false"),", indicating if hot reloading should\nbe enabled for the runtime. If this value is set to ",(0,a.kt)("inlineCode",{parentName:"p"},"false"),", it will disable\nhot reloading for any microservices managed by the runtime. If this value is\n",(0,a.kt)("inlineCode",{parentName:"p"},"true"),", hot reloading for individual microservices is managed by the\nconfiguration of that microservice."),(0,a.kt)("admonition",{type:"warning"},(0,a.kt)("p",{parentName:"admonition"},"While hot reloading is useful for development, it is not recommended for use in\nproduction.")),(0,a.kt)("p",null,"Note that ",(0,a.kt)("inlineCode",{parentName:"p"},"watch")," should be enabled for each individual service in the runtime."),(0,a.kt)("h3",{id:"allowcycles"},(0,a.kt)("inlineCode",{parentName:"h3"},"allowCycles")),(0,a.kt)("p",null,"An optional boolean, defaulting to ",(0,a.kt)("inlineCode",{parentName:"p"},"false"),", indicating if dependency cycles\nare allowed between microservices managed by the runtime. When the Platformatic\nRuntime parses the provided configuration, it examines the clients of each\nmicroservice, as well as the services of Platformatic Composer applications to\nbuild a dependency graph. A topological sort is performed on this dependency\ngraph so that each service is started after all of its dependencies have been\nstarted. If there are cycles, the topological sort fails and the Runtime does\nnot start any applications."),(0,a.kt)("p",null,"If ",(0,a.kt)("inlineCode",{parentName:"p"},"allowCycles")," is ",(0,a.kt)("inlineCode",{parentName:"p"},"true"),", the topological sort is skipped, and the\nmicroservices are started in the order specified in the configuration file."),(0,a.kt)("h3",{id:"telemetry"},(0,a.kt)("inlineCode",{parentName:"h3"},"telemetry")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://opentelemetry.io/"},"Open Telemetry")," is optionally supported with these settings:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"serviceName"))," (",(0,a.kt)("strong",{parentName:"li"},"required"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") \u2014 Name of the service as will be reported in open telemetry. In the ",(0,a.kt)("inlineCode",{parentName:"li"},"runtime")," case, the name of the services as reported in traces is ",(0,a.kt)("inlineCode",{parentName:"li"},"${serviceName}-${serviceId}"),", where ",(0,a.kt)("inlineCode",{parentName:"li"},"serviceId")," is the id of the service in the runtime."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"version"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") \u2014 Optional version (free form)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"skip"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"array"),"). Optional list of operations to skip when exporting telemetry defined ",(0,a.kt)("inlineCode",{parentName:"li"},"object")," with properties: ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"method"),": GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"path"),". e.g.: ",(0,a.kt)("inlineCode",{parentName:"li"},"/documentation/json")," "))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"exporter"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"object")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"array"),") \u2014 Exporter configuration. If not defined, the exporter defaults to ",(0,a.kt)("inlineCode",{parentName:"li"},"console"),". If an array of objects is configured, every object must be a valid exporter object. The exporter object has the following properties:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"type"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") \u2014 Exporter type. Supported values are ",(0,a.kt)("inlineCode",{parentName:"li"},"console"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"otlp"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"zipkin")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"memory")," (default: ",(0,a.kt)("inlineCode",{parentName:"li"},"console"),"). ",(0,a.kt)("inlineCode",{parentName:"li"},"memory")," is only supported for testing purposes. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"options"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"object"),") \u2014 These options are supported:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"url"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"string"),") \u2014 The URL to send the telemetry to. Required for ",(0,a.kt)("inlineCode",{parentName:"li"},"otlp")," exporter. This has no effect on ",(0,a.kt)("inlineCode",{parentName:"li"},"console")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"memory")," exporters."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"strong"},"headers"))," (",(0,a.kt)("inlineCode",{parentName:"li"},"object"),") \u2014 Optional headers to send with the telemetry. This has no effect on ",(0,a.kt)("inlineCode",{parentName:"li"},"console")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"memory")," exporters.")))))),(0,a.kt)("p",null,"Note that OTLP traces can be consumed by different solutions, like ",(0,a.kt)("a",{parentName:"p",href:"https://www.jaegertracing.io/"},"Jaeger"),". ",(0,a.kt)("a",{parentName:"p",href:"https://opentelemetry.io/ecosystem/vendors/"},"Here")," the full list."),(0,a.kt)("p",null," ",(0,a.kt)("em",{parentName:"p"},"Example")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "telemetry": {\n "serviceName": "test-service",\n "exporter": {\n "type": "otlp",\n "options": {\n "url": "http://localhost:4318/v1/traces"\n }\n }\n }\n}\n')),(0,a.kt)("h3",{id:"server"},(0,a.kt)("inlineCode",{parentName:"h3"},"server")),(0,a.kt)("p",null,"This configures the Platformatic Runtime entrypoint ",(0,a.kt)("inlineCode",{parentName:"p"},"server"),". If the entrypoint has also a ",(0,a.kt)("inlineCode",{parentName:"p"},"server")," configured, when the runtime is started, this configuration is used. "),(0,a.kt)("p",null,"See ",(0,a.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#server"},"Platformatic Service server")," for more details."),(0,a.kt)("h2",{id:"environment-variable-placeholders"},"Environment variable placeholders"),(0,a.kt)("p",null,"The value for any configuration setting can be replaced with an environment\nvariable by adding a placeholder in the configuration file, for example\n",(0,a.kt)("inlineCode",{parentName:"p"},"{PLT_ENTRYPOINT}"),"."),(0,a.kt)("p",null,"All placeholders in a configuration must be available as an environment\nvariable and must meet the\n",(0,a.kt)("a",{parentName:"p",href:"#allowed-placeholder-names"},"allowed placeholder name")," rules."),(0,a.kt)("h3",{id:"setting-environment-variables"},"Setting environment variables"),(0,a.kt)("p",null,"If a ",(0,a.kt)("inlineCode",{parentName:"p"},".env")," file exists it will automatically be loaded by Platformatic using\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/motdotla/dotenv"},(0,a.kt)("inlineCode",{parentName:"a"},"dotenv")),". For example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-plaintext",metastring:'title=".env"',title:'".env"'},"PLT_ENTRYPOINT=service\n")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},".env")," file must be located in the same folder as the Platformatic\nconfiguration file or in the current working directory."),(0,a.kt)("p",null,"Environment variables can also be set directly on the commmand line, for example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"PLT_ENTRYPOINT=service npx platformatic runtime\n")),(0,a.kt)("h3",{id:"allowed-placeholder-names"},"Allowed placeholder names"),(0,a.kt)("p",null,"Only placeholder names prefixed with ",(0,a.kt)("inlineCode",{parentName:"p"},"PLT_"),", or that are in this allow list,\nwill be dynamically replaced in the configuration file:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PORT")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"DATABASE_URL"))),(0,a.kt)("p",null,"This restriction is to avoid accidentally exposing system environment variables.\nAn error will be raised by Platformatic if it finds a configuration placeholder\nthat isn't allowed."),(0,a.kt)("p",null,"The default allow list can be extended by passing a ",(0,a.kt)("inlineCode",{parentName:"p"},"--allow-env")," CLI option\nwith a comma separated list of strings, for example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"npx platformatic runtime --allow-env=HOST,SERVER_LOGGER_LEVEL\n")),(0,a.kt)("p",null,"If ",(0,a.kt)("inlineCode",{parentName:"p"},"--allow-env")," is passed as an option to the CLI, it will be merged with the\ndefault allow list."))}c.isMDXComponent=!0}}]);
\ No newline at end of file
diff --git a/assets/js/01f3d3d0.58555425.js b/assets/js/01f3d3d0.58555425.js
new file mode 100644
index 00000000000..0dd706b4657
--- /dev/null
+++ b/assets/js/01f3d3d0.58555425.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[23142],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>f});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function l(e){for(var n=1;nid = 1
",id:"selects-row-with-id--1",level:4},{value:"Select all rows with id less than 100",id:"select-all-rows-with-id-less-than-100",level:4},{value:"Select all rows with id 1, 3, 5 or 7",id:"select-all-rows-with-id-1-3-5-or-7",level:4},{value:"Select all rows with id 1 or 3",id:"select-all-rows-with-id-1-or-3",level:4},{value:"Select all rows with id 1 or 3 and title like 'foo%'",id:"select-all-rows-with-id-1-or-3-and-title-like-foo",level:3},{value:"Reference",id:"reference",level:2},{value:"find
",id:"find",level:3},{value:"Options",id:"options",level:4},{value:"Usage",id:"usage",level:4},{value:"count
",id:"count",level:3},{value:"Options",id:"options-1",level:4},{value:"Usage",id:"usage-1",level:4},{value:"insert
",id:"insert",level:3},{value:"Options",id:"options-2",level:4},{value:"Usage",id:"usage-2",level:4},{value:"save
",id:"save",level:3},{value:"Options",id:"options-3",level:4},{value:"Usage",id:"usage-3",level:4},{value:"delete
",id:"delete",level:3},{value:"Options",id:"options-4",level:4},{value:"Usage",id:"usage-4",level:4},{value:"updateMany
",id:"updatemany",level:3},{value:"Options",id:"options-5",level:4},{value:"Usage",id:"usage-5",level:4}],s={toc:d},m="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(m,(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"api"},"API"),(0,r.kt)("p",null,"A set of operation methods are available on each entity:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#find"},(0,r.kt)("inlineCode",{parentName:"a"},"find"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#count"},(0,r.kt)("inlineCode",{parentName:"a"},"count"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#insert"},(0,r.kt)("inlineCode",{parentName:"a"},"insert"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#save"},(0,r.kt)("inlineCode",{parentName:"a"},"save"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#delete"},(0,r.kt)("inlineCode",{parentName:"a"},"delete"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#updatemany"},(0,r.kt)("inlineCode",{parentName:"a"},"updateMany")))),(0,r.kt)("h2",{id:"returned-fields"},"Returned fields"),(0,r.kt)("p",null,"The entity operation methods accept a ",(0,r.kt)("inlineCode",{parentName:"p"},"fields")," option that can specify an array of field names to be returned. If not specified, all fields will be returned."),(0,r.kt)("h2",{id:"where-clause"},"Where clause"),(0,r.kt)("p",null,"The entity operation methods accept a ",(0,r.kt)("inlineCode",{parentName:"p"},"where")," option to allow limiting of the database rows that will be affected by the operation."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"where")," object's key is the field you want to check, the value is a key/value map where the key is an operator (see the table below) and the value is the value you want to run the operator against."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Platformatic operator"),(0,r.kt)("th",{parentName:"tr",align:null},"SQL operator"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"eq"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'='"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"in"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'IN'"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"nin"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'NOT IN'"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"neq"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'<>'"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"gt"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'>'"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"gte"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'>='"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"lt"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'<'"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"lte"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'<='"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"like"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"'LIKE'"))))),(0,r.kt)("h3",{id:"examples"},"Examples"),(0,r.kt)("h4",{id:"selects-row-with-id--1"},"Selects row with ",(0,r.kt)("inlineCode",{parentName:"h4"},"id = 1")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{\n ...\n "where": {\n id: {\n eq: 1\n }\n }\n}\n')),(0,r.kt)("h4",{id:"select-all-rows-with-id-less-than-100"},"Select all rows with id less than 100"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{\n ...\n "where": {\n id: {\n lt: 100\n }\n }\n}\n')),(0,r.kt)("h4",{id:"select-all-rows-with-id-1-3-5-or-7"},"Select all rows with id 1, 3, 5 or 7"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{\n ...\n "where": {\n id: {\n in: [1, 3, 5, 7]\n }\n }\n}\n')),(0,r.kt)("p",null,"Where clause operations are by default combined with the ",(0,r.kt)("inlineCode",{parentName:"p"},"AND")," operator. To combine them with the ",(0,r.kt)("inlineCode",{parentName:"p"},"OR")," operator, use the ",(0,r.kt)("inlineCode",{parentName:"p"},"or")," key."),(0,r.kt)("h4",{id:"select-all-rows-with-id-1-or-3"},"Select all rows with id 1 or 3"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{\n ...\n "where": {\n or: [\n {\n id: {\n eq: 1\n }\n },\n {\n id: {\n eq: 3\n }\n }\n ]\n }\n}\n')),(0,r.kt)("h3",{id:"select-all-rows-with-id-1-or-3-and-title-like-foo"},"Select all rows with id 1 or 3 and title like 'foo%'"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"{\n ...\n \"where\": {\n or: [\n {\n id: {\n eq: 1\n }\n },\n {\n id: {\n eq: 3\n }\n }\n ],\n title: {\n like: 'foo%'\n }\n }\n}\n")),(0,r.kt)("h2",{id:"reference"},"Reference"),(0,r.kt)("h3",{id:"find"},(0,r.kt)("inlineCode",{parentName:"h3"},"find")),(0,r.kt)("p",null,"Retrieve data for an entity from the database."),(0,r.kt)("h4",{id:"options"},"Options"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"fields")),(0,r.kt)("td",{parentName:"tr",align:null},"Array of ",(0,r.kt)("inlineCode",{parentName:"td"},"string")),(0,r.kt)("td",{parentName:"tr",align:null},"List of fields to be returned for each object")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"where")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Object")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#where-clause"},"Where clause \ud83d\udd17"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"orderBy")),(0,r.kt)("td",{parentName:"tr",align:null},"Array of ",(0,r.kt)("inlineCode",{parentName:"td"},"Object")),(0,r.kt)("td",{parentName:"tr",align:null},"Object like ",(0,r.kt)("inlineCode",{parentName:"td"},"{ field: 'counter', direction: 'ASC' }"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"limit")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Number")),(0,r.kt)("td",{parentName:"tr",align:null},"Limits the number of returned elements")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"offset")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Number")),(0,r.kt)("td",{parentName:"tr",align:null},"The offset to start looking for rows from")))),(0,r.kt)("h4",{id:"usage"},"Usage"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"'use strict'\n\nconst { connect } = require('@platformatic/sql-mapper')\nconst { pino } = require('pino')\nconst pretty = require('pino-pretty')\nconst logger = pino(pretty())\n\nasync function main() {\n const pgConnectionString = 'postgres://postgres:postgres@127.0.0.1/postgres'\n const mapper = await connect({\n connectionString: pgConnectionString,\n log: logger,\n })\n const res = await mapper.entities.page.find({\n fields: ['id', 'title',],\n where: {\n id: {\n lt: 10\n }\n },\n })\n logger.info(res)\n await mapper.db.dispose()\n}\nmain()\n")),(0,r.kt)("h3",{id:"count"},(0,r.kt)("inlineCode",{parentName:"h3"},"count")),(0,r.kt)("p",null,"Same as ",(0,r.kt)("inlineCode",{parentName:"p"},"find"),", but only count entities. "),(0,r.kt)("h4",{id:"options-1"},"Options"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"where")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Object")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#where-clause"},"Where clause \ud83d\udd17"))))),(0,r.kt)("h4",{id:"usage-1"},"Usage"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"'use strict'\n\nconst { connect } = require('@platformatic/sql-mapper')\nconst { pino } = require('pino')\nconst pretty = require('pino-pretty')\nconst logger = pino(pretty())\n\nasync function main() {\n const pgConnectionString = 'postgres://postgres:postgres@127.0.0.1/postgres'\n const mapper = await connect({\n connectionString: pgConnectionString,\n log: logger,\n })\n const res = await mapper.entities.page.count({\n where: {\n id: {\n lt: 10\n }\n },\n })\n logger.info(res)\n await mapper.db.dispose()\n}\nmain()\n")),(0,r.kt)("h3",{id:"insert"},(0,r.kt)("inlineCode",{parentName:"h3"},"insert")),(0,r.kt)("p",null,"Insert one or more entity rows in the database."),(0,r.kt)("h4",{id:"options-2"},"Options"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"fields")),(0,r.kt)("td",{parentName:"tr",align:null},"Array of ",(0,r.kt)("inlineCode",{parentName:"td"},"string")),(0,r.kt)("td",{parentName:"tr",align:null},"List of fields to be returned for each object")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"inputs")),(0,r.kt)("td",{parentName:"tr",align:null},"Array of ",(0,r.kt)("inlineCode",{parentName:"td"},"Object")),(0,r.kt)("td",{parentName:"tr",align:null},"Each object is a new row")))),(0,r.kt)("h4",{id:"usage-2"},"Usage"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"'use strict'\n\nconst { connect } = require('@platformatic/sql-mapper')\nconst { pino } = require('pino')\nconst pretty = require('pino-pretty')\nconst logger = pino(pretty())\n\nasync function main() {\n const pgConnectionString = 'postgres://postgres:postgres@127.0.0.1/postgres'\n const mapper = await connect({\n connectionString: pgConnectionString,\n log: logger,\n })\n const res = await mapper.entities.page.insert({\n fields: ['id', 'title' ],\n inputs: [\n { title: 'Foobar' },\n { title: 'FizzBuzz' }\n ],\n })\n logger.info(res)\n /**\n 0: {\n \"id\": \"16\",\n \"title\": \"Foobar\"\n }\n 1: {\n \"id\": \"17\",\n \"title\": \"FizzBuzz\"\n }\n */\n await mapper.db.dispose()\n}\nmain()\n")),(0,r.kt)("h3",{id:"save"},(0,r.kt)("inlineCode",{parentName:"h3"},"save")),(0,r.kt)("p",null,"Create a new entity row in the database or update an existing one."),(0,r.kt)("p",null,"To update an existing entity, the ",(0,r.kt)("inlineCode",{parentName:"p"},"id")," field (or equivalent primary key) must be included in the ",(0,r.kt)("inlineCode",{parentName:"p"},"input")," object.\n",(0,r.kt)("inlineCode",{parentName:"p"},"save")," actually behaves as an ",(0,r.kt)("inlineCode",{parentName:"p"},"upsert"),", allowing both behaviours depending on the presence of the primary key field."),(0,r.kt)("h4",{id:"options-3"},"Options"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"fields")),(0,r.kt)("td",{parentName:"tr",align:null},"Array of ",(0,r.kt)("inlineCode",{parentName:"td"},"string")),(0,r.kt)("td",{parentName:"tr",align:null},"List of fields to be returned for each object")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"input")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Object")),(0,r.kt)("td",{parentName:"tr",align:null},"The single row to create/update")))),(0,r.kt)("h4",{id:"usage-3"},"Usage"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"'use strict'\nconst { connect } = require('@platformatic/sql-mapper')\nconst { pino } = require('pino')\nconst pretty = require('pino-pretty')\nconst logger = pino(pretty())\n\nasync function main() {\n const connectionString = 'postgres://postgres:postgres@127.0.0.1/postgres'\n const mapper = await connect({\n connectionString: connectionString,\n log: logger,\n })\n const res = await mapper.entities.page.save({\n fields: ['id', 'title' ],\n input: { id: 1, title: 'FizzBuzz' },\n })\n logger.info(res)\n await mapper.db.dispose()\n}\nmain()\n")),(0,r.kt)("h3",{id:"delete"},(0,r.kt)("inlineCode",{parentName:"h3"},"delete")),(0,r.kt)("p",null,"Delete one or more entity rows from the database, depending on the ",(0,r.kt)("inlineCode",{parentName:"p"},"where")," option. Returns the data for all deleted objects."),(0,r.kt)("h4",{id:"options-4"},"Options"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"fields")),(0,r.kt)("td",{parentName:"tr",align:null},"Array of ",(0,r.kt)("inlineCode",{parentName:"td"},"string")),(0,r.kt)("td",{parentName:"tr",align:null},"List of fields to be returned for each object")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"where")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Object")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#where-clause"},"Where clause \ud83d\udd17"))))),(0,r.kt)("h4",{id:"usage-4"},"Usage"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"'use strict'\nconst { connect } = require('@platformatic/sql-mapper')\nconst { pino } = require('pino')\nconst pretty = require('pino-pretty')\nconst logger = pino(pretty())\n\nasync function main() {\n const connectionString = 'postgres://postgres:postgres@127.0.0.1/postgres'\n const mapper = await connect({\n connectionString: connectionString,\n log: logger,\n })\n const res = await mapper.entities.page.delete({\n fields: ['id', 'title',],\n where: {\n id: {\n lt: 4\n }\n },\n })\n logger.info(res)\n await mapper.db.dispose()\n}\nmain()\n\n")),(0,r.kt)("h3",{id:"updatemany"},(0,r.kt)("inlineCode",{parentName:"h3"},"updateMany")),(0,r.kt)("p",null,"Update one or more entity rows from the database, depending on the ",(0,r.kt)("inlineCode",{parentName:"p"},"where")," option. Returns the data for all updated objects."),(0,r.kt)("h4",{id:"options-5"},"Options"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Name"),(0,r.kt)("th",{parentName:"tr",align:null},"Type"),(0,r.kt)("th",{parentName:"tr",align:null},"Description"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"where")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Object")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"#where-clause"},"Where clause \ud83d\udd17"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"input")),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"Object")),(0,r.kt)("td",{parentName:"tr",align:null},"The new values that want to update")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"fields")),(0,r.kt)("td",{parentName:"tr",align:null},"Array of ",(0,r.kt)("inlineCode",{parentName:"td"},"string")),(0,r.kt)("td",{parentName:"tr",align:null},"List of fields to be returned for each object")))),(0,r.kt)("h4",{id:"usage-5"},"Usage"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"'use strict'\nconst { connect } = require('@platformatic/sql-mapper')\nconst { pino } = require('pino')\nconst pretty = require('pino-pretty')\nconst logger = pino(pretty())\n\nasync function main() {\n const connectionString = 'postgres://postgres:postgres@127.0.0.1/postgres'\n const mapper = await connect({\n connectionString: connectionString,\n log: logger,\n })\n const res = await mapper.entities.page.updateMany({\n fields: ['id', 'title',],\n where: {\n counter: {\n gte: 30\n }\n },\n input: { \n title: 'Updated title'\n }\n })\n logger.info(res)\n await mapper.db.dispose()\n}\nmain()\n\n")))}c.isMDXComponent=!0}}]);
\ No newline at end of file
diff --git a/assets/js/03cb791b.122203d5.js b/assets/js/03cb791b.122203d5.js
new file mode 100644
index 00000000000..9bb36b75820
--- /dev/null
+++ b/assets/js/03cb791b.122203d5.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[15728],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;tget[ENTITY]by[PRIMARY_KEY]
",id:"getentitybyprimary_key",level:3},{value:"Example",id:"example-1",level:4},{value:"count[ENTITIES]
",id:"countentities",level:3},{value:"Pagination",id:"pagination",level:2},{value:"Limit",id:"limit",level:3},{value:"Offset",id:"offset",level:3}],u={toc:p},c="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(c,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"queries"},"Queries"),(0,a.kt)("p",null,"A GraphQL query is automatically added to the GraphQL schema for each database\ntable, along with a complete mapping for all table fields."),(0,a.kt)("h2",{id:"example"},"Example"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"'use strict'\n\nconst Fastify = require('fastify')\nconst graphqlPlugin = require('@platformatic/sql-graphql')\nconst sqlMapper = require('@platformatic/sql-mapper')\nasync function main() {\n const app = Fastify({\n logger: {\n level: 'info'\n }\n })\n app.register(sqlMapper, {\n connectionString: 'postgres://postgres:postgres@127.0.0.1/postgres'\n })\n app.register(graphqlPlugin, {\n graphiql: true\n })\n const res = await app.inject({\n method: 'POST',\n url: '/graphql',\n body: {\n query: `\n query{\n pages{\n id,\n title\n }\n }\n `\n }\n })\n const result = await res.json()\n console.log(result.data)\n await app.close()\n}\nmain()\n")),(0,a.kt)("h2",{id:"advanced-queries"},"Advanced Queries"),(0,a.kt)("p",null,"The following additional queries are added to the GraphQL schema for each entity:"),(0,a.kt)("h3",{id:"getentitybyprimary_key"},(0,a.kt)("inlineCode",{parentName:"h3"},"get[ENTITY]by[PRIMARY_KEY]")),(0,a.kt)("p",null,"If you have a table ",(0,a.kt)("inlineCode",{parentName:"p"},"pages")," with the field ",(0,a.kt)("inlineCode",{parentName:"p"},"id")," as the primary key, you can run\na query called ",(0,a.kt)("inlineCode",{parentName:"p"},"getPageById"),"."),(0,a.kt)("h4",{id:"example-1"},"Example"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"...\nconst res = await app.inject({\n method: 'POST',\n url: '/graphql',\n body: {\n query: `\n query{\n getPageById(id: 3) {\n id,\n title\n }\n }\n `\n }\n})\nconst result = await res.json()\nconsole.log(result.data) // { getPageById: { id: '3', title: 'A fiction' } }\n")),(0,a.kt)("h3",{id:"countentities"},(0,a.kt)("inlineCode",{parentName:"h3"},"count[ENTITIES]")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"...\nconst res = await app.inject({\n method: 'POST',\n url: '/graphql',\n body: {\n query: `\n query {\n countPages {\n total\n }\n }\n `\n }\n})\nconst result = await res.json()\nconsole.log(result.data) // { countMovies : { total: { 17 } }\n")),(0,a.kt)("h2",{id:"pagination"},"Pagination"),(0,a.kt)("p",null,"The Platformatic DB supports for result's pagination through input parameters: ",(0,a.kt)("inlineCode",{parentName:"p"},"limit")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"offset")),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"Example")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"{\n users(limit:5, offset: 10) {\n name\n }\n}\n")),(0,a.kt)("p",null,"It returns 5 users starting from position 10."),(0,a.kt)("h3",{id:"limit"},"Limit"),(0,a.kt)("p",null,"By default a ",(0,a.kt)("em",{parentName:"p"},"limit")," value (",(0,a.kt)("inlineCode",{parentName:"p"},"10"),") is applied to each request."),(0,a.kt)("p",null,"Clients can override this behavior by passing a value.\nIn this case the server validates the input and an error is return if exceeds the ",(0,a.kt)("inlineCode",{parentName:"p"},"max")," accepted value (",(0,a.kt)("inlineCode",{parentName:"p"},"100"),")."),(0,a.kt)("p",null,"Limit's values can be customized through configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n ...\n "db": {\n ...\n "limit": {\n "default": 50,\n "max": 1000\n }\n }\n}\n')),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"Limit")," only accepts values ",(0,a.kt)("inlineCode",{parentName:"p"},">= 0"),". Otherwise an error is return."),(0,a.kt)("h3",{id:"offset"},"Offset"),(0,a.kt)("p",null,"By default ",(0,a.kt)("em",{parentName:"p"},"offset")," is not applied to the request.\nClients can override this behavior by passing a value."),(0,a.kt)("p",null,(0,a.kt)("em",{parentName:"p"},"Offset")," only accepts values ",(0,a.kt)("inlineCode",{parentName:"p"},">= 0"),". Otherwise an error is return."))}d.isMDXComponent=!0}}]);
\ No newline at end of file
diff --git a/assets/js/043eb32f.e9211500.js b/assets/js/043eb32f.e9211500.js
new file mode 100644
index 00000000000..73500f2cd8b
--- /dev/null
+++ b/assets/js/043eb32f.e9211500.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[966],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t[ENTITY]Saved
",id:"entitysaved",level:2},{value:"[ENTITY]Deleted
",id:"entitydeleted",level:2}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"subscription"},"Subscription"),(0,i.kt)("p",null,"When the GraphQL plugin is loaded, some subscriptions are automatically adding to\nthe GraphQL schema if the ",(0,i.kt)("inlineCode",{parentName:"p"},"@platformatic/sql-events")," plugin has been previously registered."),(0,i.kt)("p",null,"It's possible to avoid creating the subscriptions for a given entity by adding the ",(0,i.kt)("inlineCode",{parentName:"p"},"subscriptionIgnore")," config,\nlike so: ",(0,i.kt)("inlineCode",{parentName:"p"},"subscriptionIgnore: ['page']"),"."),(0,i.kt)("h2",{id:"entitysaved"},(0,i.kt)("inlineCode",{parentName:"h2"},"[ENTITY]Saved")),(0,i.kt)("p",null,"Published whenever an entity is saved, e.g. when the mutation ",(0,i.kt)("inlineCode",{parentName:"p"},"insert[ENTITY]")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"save[ENTITY]")," are called."),(0,i.kt)("h2",{id:"entitydeleted"},(0,i.kt)("inlineCode",{parentName:"h2"},"[ENTITY]Deleted")),(0,i.kt)("p",null,"Published whenever an entity is deleted, e.g. when the mutation ",(0,i.kt)("inlineCode",{parentName:"p"},"delete[ENTITY]")," is called.."))}d.isMDXComponent=!0}}]);
\ No newline at end of file
diff --git a/assets/js/06912af6.fea26528.js b/assets/js/06912af6.fea26528.js
new file mode 100644
index 00000000000..32329075c16
--- /dev/null
+++ b/assets/js/06912af6.fea26528.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[52746],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>y});var o=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;tsqlite
for debugging",id:"adding-sqlite-for-debugging",level:2}],c={toc:p},s="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(s,(0,o.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"advanced-flyio-deployment"},"Advanced Fly.io Deployment"),(0,a.kt)("p",null,"Techniques used in this guide are based on ",(0,a.kt)("a",{parentName:"p",href:"/docs/1.9.0/guides/deployment/deploy-to-fly-io-with-sqlite"},"the Deploy to Fly.io with SQLite"),"\ndeployment guide."),(0,a.kt)("h2",{id:"adding-sqlite-for-debugging"},"Adding ",(0,a.kt)("inlineCode",{parentName:"h2"},"sqlite")," for debugging"),(0,a.kt)("p",null,"With a combination of Docker and Fly.io, you can create an easy way to debug\nyour sqlite aplication without stopping your application or exporting the data.\nAt the end of this guide, you will be able to run ",(0,a.kt)("inlineCode",{parentName:"p"},"fly ssh console -C db-cli")," to\nbe dropped into your remote database."),(0,a.kt)("p",null,"Start by creating a script for launching the database, calling it ",(0,a.kt)("strong",{parentName:"p"},"db-cli.sh"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"#!/bin/sh\nset -x\n# DSN will be defined in the Dockerfile\nsqlite3 $DSN\n")),(0,a.kt)("p",null,"Create a new ",(0,a.kt)("strong",{parentName:"p"},"Dockerfile")," which will act as the build and deployment image:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-dockerfile"},'FROM node:18-alpine\n\n# Setup sqlite viewer\nRUN apk add sqlite\nENV DSN "/app/.platformatic/data/app.db"\nCOPY db-cli.sh /usr/local/bin/db-cli\nRUN chmod +x /usr/local/bin/db-cli\n\nWORKDIR /app\nCOPY package.json package.json\nCOPY package-lock.json package-lock.json\n\nRUN npm ci --omit=dev\n\nCOPY platformatic.db.json platformatic.db.json\n\nCOPY migrations migrations\n# Uncomment if your application is running a plugin\n# COPY plugin.js plugin.js\n\nEXPOSE 8080\n\nCMD ["npm", "start"]\n')),(0,a.kt)("p",null,"Add a ",(0,a.kt)("inlineCode",{parentName:"p"},"start")," script to your ",(0,a.kt)("strong",{parentName:"p"},"package.json"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-json"},'{\n "scripts": {\n "start": "platformatic db"\n }\n}\n')),(0,a.kt)("p",null,"With Fly, it becomes straightforward to connect directly to the database by\nrunning the following command from your local machine:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"fly ssh console -C db-cli\n")))}u.isMDXComponent=!0}}]);
\ No newline at end of file
diff --git a/assets/js/06a00f9e.811901cc.js b/assets/js/06a00f9e.811901cc.js
new file mode 100644
index 00000000000..15652b117ac
--- /dev/null
+++ b/assets/js/06a00f9e.811901cc.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[27480],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;tWe\'ll list all the movie quotes here.
\n\n\n{quote.quote}
\n
\n \u2014 {quote.saidBy}, {quote.movie?.name}\n
\nNo movie quotes have been added.
\n )}\n// highlight-end\n\n// highlight-next-line\n\n// highlight-next-line\n{quote.quote}
\n
\n \u2014 {quote.saidBy}, {quote.movie?.name}\n
\n// highlight-next-line\nNo movie quotes have been added.
\n )}\nThere was an error saving the quote. Please try again.
}\n{loadError &&There was an error loading the quote. Please try again.
}\n\n\n')),(0,o.kt)("p",null,"Create a new page file, ",(0,o.kt)("strong",{parentName:"p"},(0,o.kt)("inlineCode",{parentName:"strong"},"src/pages/add.astro")),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-astro"},'---\nimport Layout from \'../layouts/Layout.astro\';\nimport QuoteForm from \'../components/QuoteForm.astro\';\nimport type { QuoteFormData } from \'../components/QuoteForm.astro\';\n\nlet formData: QuoteFormData = {};\nlet saveError = false;\n---\n\nNo movie quotes have been added.
\n )}\nThere was an error deleting the quote. Please try again.
\nArchive