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..b237cb3eb7c --- /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/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/0104c450.f496fd9d.js b/assets/js/0104c450.f496fd9d.js
new file mode 100644
index 00000000000..6640b7147f4
--- /dev/null
+++ b/assets/js/0104c450.f496fd9d.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[2938],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>u});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 o(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 i(e){for(var t=1;tbuildServer()
",id:"buildserver",level:2},{value:"loadConfig()
",id:"loadconfig",level:2},{value:"start()
",id:"start",level:2},{value:"startCommand()
",id:"startcommand",level:2}],s={toc:l},m="wrapper";function f(e){let{components:t,...n}=e;return(0,a.kt)(m,(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"programmatic-api"},"Programmatic API"),(0,a.kt)("p",null,"In many cases it's useful to start Platformatic applications using an API\ninstead of the command line. The ",(0,a.kt)("inlineCode",{parentName:"p"},"@platformatic/runtime")," API makes it simple to\nwork with different application types (e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"service"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"db"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"composer")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"runtime"),") without\nneeding to know the application type a priori."),(0,a.kt)("h2",{id:"buildserver"},(0,a.kt)("inlineCode",{parentName:"h2"},"buildServer()")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"buildServer")," function creates a server from a provided configuration\nobject or configuration filename.\nThe config can be of either Platformatic Service, Platformatic DB,\nPlatformatic Composer or any other application built on top of\n",(0,a.kt)("a",{parentName:"p",href:"/docs/1.8.1/reference/service/programmatic"},"Platformatic Service"),"."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import { buildServer } from '@platformatic/runtime'\n\nconst app = await buildServer('path/to/platformatic.runtime.json')\nconst entrypointUrl = await app.start()\n\n// Make a request to the entrypoint.\nconst res = await fetch(entrypointUrl)\nconsole.log(await res.json())\n\n// Do other interesting things.\n\nawait app.close()\n")),(0,a.kt)("p",null,"It is also possible to customize the configuration:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import { buildServer } from '@platformatic/runtime'\n\nconst config = {\n // $schema: 'https://platformatic.dev/schemas/v0.39.0/runtime',\n // $schema: 'https://platformatic.dev/schemas/v0.39.0/service',\n // $schema: 'https://platformatic.dev/schemas/v0.39.0/db',\n // $schema: 'https://platformatic.dev/schemas/v0.39.0/composer'\n ...\n}\nconst app = await buildServer(config)\n\nawait app.start()\n")),(0,a.kt)("h2",{id:"loadconfig"},(0,a.kt)("inlineCode",{parentName:"h2"},"loadConfig()")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"loadConfig")," function is used to read and parse a configuration file for\nan arbitrary Platformatic application."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import { loadConfig } from '@platformatic/runtime'\n\n// Read the config based on command line arguments. loadConfig() will detect\n// the application type.\nconst config = await loadConfig({}, ['-c', '/path/to/platformatic.config.json'])\n\n// Read the config based on command line arguments. The application type can\n// be provided explicitly.\nconst config = await loadConfig(\n {},\n ['-c', '/path/to/platformatic.config.json']\n)\n\n// Default config can be specified.\nconst config = await loadConfig(\n {},\n ['-c', '/path/to/platformatic.config.json'],\n { key: 'value' }\n)\n")),(0,a.kt)("h2",{id:"start"},(0,a.kt)("inlineCode",{parentName:"h2"},"start()")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"start")," function loads a configuration, builds a server, and starts the\nserver. However, the server is not returned."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import { start } from '@platformatic/runtime'\n\nawait start(['-c', '/path/to/platformatic.config.json])\n")),(0,a.kt)("h2",{id:"startcommand"},(0,a.kt)("inlineCode",{parentName:"h2"},"startCommand()")),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"startCommand")," function is similar to ",(0,a.kt)("inlineCode",{parentName:"p"},"start"),". However, if an exception\noccurs, ",(0,a.kt)("inlineCode",{parentName:"p"},"startCommand")," logs the error and exits the process. This is different\nfrom ",(0,a.kt)("inlineCode",{parentName:"p"},"start"),", which throws the exception."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"import { startCommand } from '@platformatic/runtime'\n\nawait startCommand(['-c', '/path/to/platformatic.config.json])\n")))}f.isMDXComponent=!0}}]);
\ No newline at end of file
diff --git a/assets/js/0136c26d.4b6dbaef.js b/assets/js/0136c26d.4b6dbaef.js
new file mode 100644
index 00000000000..ebd4669c580
--- /dev/null
+++ b/assets/js/0136c26d.4b6dbaef.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[19052],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>k});var a=n(67294);function r(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 a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;tserver
",id:"server",level:3},{value:"db
",id:"db",level:3},{value:"metrics
",id:"metrics",level:3},{value:"migrations
",id:"migrations",level:3},{value:"plugins
",id:"plugins",level:3},{value:"watch
",id:"watch",level:3},{value:"authorization
",id:"authorization",level:3},{value:"Example",id:"example",level:4},{value:"telemetry
",id:"telemetry",level:3},{value:"watch
",id:"watch-1",level:3},{value:"clients
",id:"clients",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},{value:"Sample Configuration",id:"sample-configuration",level:2}],m={toc:s},d="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(d,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"configuration"},"Configuration"),(0,r.kt)("p",null,"Platformatic DB is configured with a configuration file. It supports the use\nof environment variables as setting values with ",(0,r.kt)("a",{parentName:"p",href:"#configuration-placeholders"},"configuration placeholders"),"."),(0,r.kt)("h2",{id:"configuration-file"},"Configuration file"),(0,r.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,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"platformatic.db.json")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"platformatic.db.json5")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"platformatic.db.yml")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"platformatic.db.yaml")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"platformatic.db.tml")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"platformatic.db.toml"))),(0,r.kt)("p",null,"Alternatively, a ",(0,r.kt)("a",{parentName:"p",href:"/docs/1.8.1/reference/cli#db"},(0,r.kt)("inlineCode",{parentName:"a"},"--config")," option")," with a configuration\nfilepath can be passed to most ",(0,r.kt)("inlineCode",{parentName:"p"},"platformatic db")," CLI commands."),(0,r.kt)("p",null,"The configuration examples in this reference use JSON."),(0,r.kt)("h3",{id:"supported-formats"},"Supported formats"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:"left"},"Format"),(0,r.kt)("th",{parentName:"tr",align:"left"},"Extensions"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"left"},"JSON"),(0,r.kt)("td",{parentName:"tr",align:"left"},(0,r.kt)("inlineCode",{parentName:"td"},".json"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"left"},"JSON5"),(0,r.kt)("td",{parentName:"tr",align:"left"},(0,r.kt)("inlineCode",{parentName:"td"},".json5"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"left"},"YAML"),(0,r.kt)("td",{parentName:"tr",align:"left"},(0,r.kt)("inlineCode",{parentName:"td"},".yml"),", ",(0,r.kt)("inlineCode",{parentName:"td"},".yaml"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:"left"},"TOML"),(0,r.kt)("td",{parentName:"tr",align:"left"},(0,r.kt)("inlineCode",{parentName:"td"},".tml"))))),(0,r.kt)("p",null,"Comments are supported by the JSON5, YAML and TOML file formats."),(0,r.kt)("h2",{id:"settings"},"Settings"),(0,r.kt)("p",null,"Configuration settings are organised into the following groups:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#server"},(0,r.kt)("inlineCode",{parentName:"a"},"server"))," ",(0,r.kt)("strong",{parentName:"li"},"(required)")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#db"},(0,r.kt)("inlineCode",{parentName:"a"},"db"))," ",(0,r.kt)("strong",{parentName:"li"},"(required)")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#metrics"},(0,r.kt)("inlineCode",{parentName:"a"},"metrics"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#migrations"},(0,r.kt)("inlineCode",{parentName:"a"},"migrations"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#plugins"},(0,r.kt)("inlineCode",{parentName:"a"},"plugins"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#authorization"},(0,r.kt)("inlineCode",{parentName:"a"},"authorization"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#telemetry"},(0,r.kt)("inlineCode",{parentName:"a"},"telemetry"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#watch"},(0,r.kt)("inlineCode",{parentName:"a"},"watch"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"#clients"},(0,r.kt)("inlineCode",{parentName:"a"},"clients")))),(0,r.kt)("p",null,"Sensitive configuration settings, such as a database connection URL that contains\na password, should be set using ",(0,r.kt)("a",{parentName:"p",href:"#configuration-placeholders"},"configuration placeholders"),"."),(0,r.kt)("h3",{id:"server"},(0,r.kt)("inlineCode",{parentName:"h3"},"server")),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#server"},"Platformatic Service server")," for more details."),(0,r.kt)("h3",{id:"db"},(0,r.kt)("inlineCode",{parentName:"h3"},"db")),(0,r.kt)("p",null,"A ",(0,r.kt)("strong",{parentName:"p"},"required")," object with the following settings:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"connectionString"))," (",(0,r.kt)("strong",{parentName:"p"},"required"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"string"),") \u2014 Database connection URL."),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Example: ",(0,r.kt)("inlineCode",{parentName:"li"},"postgres://user:password@my-database:5432/db-name")))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"}," ",(0,r.kt)("inlineCode",{parentName:"strong"},"schema"))," (array of ",(0,r.kt)("inlineCode",{parentName:"p"},"string"),") - Currently supported only for postgres, schemas used tolook for entities. If not provided, the default ",(0,r.kt)("inlineCode",{parentName:"p"},"public")," schema is used."),(0,r.kt)("p",{parentName:"li"},(0,r.kt)("em",{parentName:"p"},"Examples")))),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},' "db": {\n "connectionString": "(...)",\n "schema": [\n "schema1", "schema2"\n ],\n ...\n\n },\n\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Platformatic DB supports MySQL, MariaDB, PostgreSQL and SQLite.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"graphql"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"object"),", default: ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),") \u2014 Controls the GraphQL API interface, with optional GraphiQL UI."),(0,r.kt)("p",{parentName:"li"},(0,r.kt)("em",{parentName:"p"},"Examples")),(0,r.kt)("p",{parentName:"li"},"Enables GraphQL support"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "graphql": true\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"Enables GraphQL support with the ",(0,r.kt)("inlineCode",{parentName:"p"},"enabled")," option"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "graphql": {\n ...\n "enabled": true\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"Enables GraphQL support with GraphiQL"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "graphql": {\n "graphiql": true\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"It's possible to selectively ignore entites:"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "graphql": {\n "ignore": {\n "categories": true\n }\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"It's possible to selectively ignore fields:"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "graphql": {\n "ignore": {\n "categories": {\n "name": true\n }\n }\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"It's possible to add a custom GraphQL schema during the startup:"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "graphql": {\n "schemaPath": "path/to/schema.graphql"\n }\n }\n }\n}\n'))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"openapi"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"object"),", default: ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),") \u2014 Enables OpenAPI REST support."),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"If value is an object, all ",(0,r.kt)("a",{parentName:"li",href:"https://swagger.io/specification/"},"OpenAPI v3")," allowed properties can be passed. Also a ",(0,r.kt)("inlineCode",{parentName:"li"},"prefix")," property can be passed to set the OpenAPI prefix."),(0,r.kt)("li",{parentName:"ul"},"Platformatic DB uses ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/fastify/fastify-swagger"},(0,r.kt)("inlineCode",{parentName:"a"},"@fastify/swagger"))," under the hood to manage this configuration.")),(0,r.kt)("p",{parentName:"li"},(0,r.kt)("em",{parentName:"p"},"Examples")),(0,r.kt)("p",{parentName:"li"},"Enables OpenAPI"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "openapi": true\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"Enables OpenAPI using the ",(0,r.kt)("inlineCode",{parentName:"p"},"enabled")," option"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "openapi": {\n ...\n "enabled": true\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"Enables OpenAPI with prefix"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "openapi": {\n "prefix": "/api"\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"Enables OpenAPI with options"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "openapi": {\n "info": {\n "title": "Platformatic DB",\n "description": "Exposing a SQL database as REST"\n }\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"You can for example add the ",(0,r.kt)("inlineCode",{parentName:"p"},"security")," section, so that Swagger will allow you to add the authentication header to your requests.\nIn the following code snippet, we're adding a Bearer token in the form of a ",(0,r.kt)("a",{parentName:"p",href:"/docs/1.8.1/reference/db/authorization/strategies#json-web-token-jwt"},"JWT"),":"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "openapi": {\n ...\n "security": [{ "bearerAuth": [] }],\n "components": {\n "securitySchemes": {\n "bearerAuth": {\n "type": "http",\n "scheme": "bearer",\n "bearerFormat": "JWT"\n }\n }\n }\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"It's possible to selectively ignore entites:"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "openapi": {\n "ignore": {\n "categories": true\n }\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"It's possible to selectively ignore fields:"),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "openapi": {\n "ignore": {\n "categories": {\n "name": true\n }\n }\n }\n }\n}\n'))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"autoTimestamp"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"object"),") - Generate timestamp automatically when inserting/updating records.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"poolSize"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"number"),", default: ",(0,r.kt)("inlineCode",{parentName:"p"},"10"),") \u2014 Maximum number of connections in the connection pool.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"idleTimeoutMilliseconds"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"number"),", default: ",(0,r.kt)("inlineCode",{parentName:"p"},"30000"),") - Max milliseconds a client can go unused before it is removed from the pool and destroyed.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"queueTimeoutMilliseconds"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"number"),", default: ",(0,r.kt)("inlineCode",{parentName:"p"},"60000"),") - Number of milliseconds to wait for a connection from the connection pool before throwing a timeout error.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"acquireLockTimeoutMilliseconds"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"number"),", default: ",(0,r.kt)("inlineCode",{parentName:"p"},"60000"),") - Number of milliseconds to wait for a lock on a connection/transaction.")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"limit"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"object"),") - Set the default and max limit for pagination. Default is 10, max is 1000."),(0,r.kt)("p",{parentName:"li"},(0,r.kt)("em",{parentName:"p"},"Examples")),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "limit": {\n "default": 10,\n "max": 1000\n }\n }\n}\n'))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"ignore"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"object"),") \u2014 Key/value object that defines which database tables should not be mapped as API entities."),(0,r.kt)("p",{parentName:"li"},(0,r.kt)("em",{parentName:"p"},"Examples")),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "ignore": {\n "versions": true // "versions" table will be not mapped with GraphQL/REST APIs\n }\n }\n}\n'))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"events"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"object"),", default: ",(0,r.kt)("inlineCode",{parentName:"p"},"true"),") \u2014 Controls the support for events published by the SQL mapping layer.\nIf enabled, this option add support for GraphQL Subscription over WebSocket. By default it uses an in-process message broker.\nIt's possible to configure it to use Redis instead."),(0,r.kt)("p",{parentName:"li"},(0,r.kt)("em",{parentName:"p"},"Examples")),(0,r.kt)("p",{parentName:"li"},"Enable events using the ",(0,r.kt)("inlineCode",{parentName:"p"},"enabled")," option."),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "events": {\n ...\n "enabled": true\n }\n }\n}\n')),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "events": {\n "connectionString": "redis://:password@redishost.com:6380/"\n }\n }\n}\n'))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},(0,r.kt)("inlineCode",{parentName:"strong"},"schemalock"))," (",(0,r.kt)("inlineCode",{parentName:"p"},"boolean")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"object"),", default: ",(0,r.kt)("inlineCode",{parentName:"p"},"false"),") \u2014 Controls the caching of the database schema on disk.\nIf set to ",(0,r.kt)("inlineCode",{parentName:"p"},"true")," the database schema metadata is stored inside a ",(0,r.kt)("inlineCode",{parentName:"p"},"schema.lock")," file.\nIt's also possible to configure the location of that file by specifying a path, like so:"),(0,r.kt)("p",{parentName:"li"},(0,r.kt)("em",{parentName:"p"},"Examples")),(0,r.kt)("pre",{parentName:"li"},(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "db": {\n ...\n "schemalock": {\n "path": "./dbmetadata"\n }\n }\n}\n')),(0,r.kt)("p",{parentName:"li"},"Starting Platformatic DB or running a migration will automatically create the schemalock file."))),(0,r.kt)("h3",{id:"metrics"},(0,r.kt)("inlineCode",{parentName:"h3"},"metrics")),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#metrics"},"Platformatic Service metrics")," for more details."),(0,r.kt)("h3",{id:"migrations"},(0,r.kt)("inlineCode",{parentName:"h3"},"migrations")),(0,r.kt)("p",null,"Configures ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/rickbergfalk/postgrator"},"Postgrator")," to run migrations against the database."),(0,r.kt)("p",null,"An optional object with the following settings:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"strong"},"dir"))," (",(0,r.kt)("strong",{parentName:"li"},"required"),", ",(0,r.kt)("inlineCode",{parentName:"li"},"string"),"): Relative path to the migrations directory."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},(0,r.kt)("inlineCode",{parentName:"strong"},"autoApply"))," (",(0,r.kt)("inlineCode",{parentName:"li"},"boolean"),", default: ",(0,r.kt)("inlineCode",{parentName:"li"},"false"),"): Automatically apply migrations when Platformatic DB server starts.")),(0,r.kt)("h3",{id:"plugins"},(0,r.kt)("inlineCode",{parentName:"h3"},"plugins")),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#plugins"},"Platformatic Service plugins")," for more details."),(0,r.kt)("h3",{id:"watch"},(0,r.kt)("inlineCode",{parentName:"h3"},"watch")),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#watch"},"Platformatic Service watch")," for more details."),(0,r.kt)("h3",{id:"authorization"},(0,r.kt)("inlineCode",{parentName:"h3"},"authorization")),(0,r.kt)("p",null,"An optional object with the following settings:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"adminSecret")," (",(0,r.kt)("inlineCode",{parentName:"li"},"string"),"): A secret that should be sent in an\n",(0,r.kt)("inlineCode",{parentName:"li"},"x-platformatic-admin-secret")," HTTP header when performing GraphQL/REST API\ncalls. Use an ",(0,r.kt)("a",{parentName:"li",href:"#environment-variable-placeholders"},"environment variable placeholder"),"\nto securely provide the value for this setting."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"roleKey")," (",(0,r.kt)("inlineCode",{parentName:"li"},"string"),", default: ",(0,r.kt)("inlineCode",{parentName:"li"},"X-PLATFORMATIC-ROLE"),"): The name of the key in user\nmetadata that is used to store the user's roles. See ",(0,r.kt)("a",{parentName:"li",href:"/docs/reference/db/authorization/user-roles-metadata#role-configuration"},"Role configuration"),"."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"anonymousRole")," (",(0,r.kt)("inlineCode",{parentName:"li"},"string"),", default: ",(0,r.kt)("inlineCode",{parentName:"li"},"anonymous"),"): The name of the anonymous role. See ",(0,r.kt)("a",{parentName:"li",href:"/docs/reference/db/authorization/user-roles-metadata#role-configuration"},"Role configuration"),"."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"jwt")," (",(0,r.kt)("inlineCode",{parentName:"li"},"object"),"): Configuration for the ",(0,r.kt)("a",{parentName:"li",href:"/docs/reference/db/authorization/strategies#json-web-token-jwt"},"JWT authorization strategy"),".\nAny option accepted by ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/fastify/fastify-jwt"},(0,r.kt)("inlineCode",{parentName:"a"},"@fastify/jwt")),"\ncan be passed in this object.",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"secret")," (required, ",(0,r.kt)("inlineCode",{parentName:"li"},"string")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"object"),"): The secret key that the JWT was signed with.\nSee the ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/fastify/fastify-jwt#secret-required"},(0,r.kt)("inlineCode",{parentName:"a"},"@fastify/jwt")," documentation"),"\nfor accepted string and object values. Use an ",(0,r.kt)("a",{parentName:"li",href:"#environment-variable-placeholders"},"environment variable placeholder"),"\nto securely provide the value for this setting."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"jwks")," (",(0,r.kt)("inlineCode",{parentName:"li"},"boolean")," or ",(0,r.kt)("inlineCode",{parentName:"li"},"object"),"): Configure authorization with JSON Web Key Sets (JWKS). See the ",(0,r.kt)("a",{parentName:"li",href:"/docs/reference/db/authorization/strategies#json-web-key-sets-jwks"},"JWKS documentation"),"."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"namespace")," (",(0,r.kt)("inlineCode",{parentName:"li"},"string"),"): Configure a ",(0,r.kt)("a",{parentName:"li",href:"/docs/reference/db/authorization/strategies#jwt-custom-claim-namespace"},"JWT Custom Claim Namespace"),"\nto avoid name collisions."))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"webhook")," (",(0,r.kt)("inlineCode",{parentName:"li"},"object"),"): Configuration for the ",(0,r.kt)("a",{parentName:"li",href:"/docs/reference/db/authorization/strategies#webhook"},"Webhook authorization strategy"),".",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"url")," (required, ",(0,r.kt)("inlineCode",{parentName:"li"},"string"),"): Webhook URL that Platformatic DB will make a\nPOST request to."))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"rules")," (",(0,r.kt)("inlineCode",{parentName:"li"},"array"),"): Authorization rules that describe the CRUD actions that\nusers are allowed to perform against entities. See ",(0,r.kt)("a",{parentName:"li",href:"/docs/reference/db/authorization/rules"},"Rules"),"\ndocumentation.")),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"If an ",(0,r.kt)("inlineCode",{parentName:"p"},"authorization")," object is present, but no rules are specified, no CRUD\noperations are allowed unless ",(0,r.kt)("inlineCode",{parentName:"p"},"adminSecret")," is passed.")),(0,r.kt)("h4",{id:"example"},"Example"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="platformatic.db.json"',title:'"platformatic.db.json"'},'{\n "authorization": {\n "jwt": {\n "secret": "{PLT_AUTHORIZATION_JWT_SECRET}"\n },\n "rules": [\n ...\n ]\n }\n}\n')),(0,r.kt)("h3",{id:"telemetry"},(0,r.kt)("inlineCode",{parentName:"h3"},"telemetry")),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#telemetry"},"Platformatic Service telemetry")," for more details."),(0,r.kt)("h3",{id:"watch-1"},(0,r.kt)("inlineCode",{parentName:"h3"},"watch")),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#watch"},"Platformatic Service watch")," for more details."),(0,r.kt)("h3",{id:"clients"},(0,r.kt)("inlineCode",{parentName:"h3"},"clients")),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#clients"},"Platformatic Service clients")," for more details."),(0,r.kt)("h2",{id:"environment-variable-placeholders"},"Environment variable placeholders"),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#environment-variable-placeholders"},"Environment variable placeholders")," for more details."),(0,r.kt)("h3",{id:"setting-environment-variables"},"Setting environment variables"),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#setting-environment-variables"},"Setting environment variables")," for more details."),(0,r.kt)("h3",{id:"allowed-placeholder-names"},"Allowed placeholder names"),(0,r.kt)("p",null,"See ",(0,r.kt)("a",{parentName:"p",href:"/docs/next/reference/service/configuration#allowed-placeholder-names"},"Allowed placeholder names")," for more details."),(0,r.kt)("h2",{id:"sample-configuration"},"Sample Configuration"),(0,r.kt)("p",null,"This is a bare minimum configuration for Platformatic DB. Uses a local ",(0,r.kt)("inlineCode",{parentName:"p"},"./db.sqlite")," SQLite database, with OpenAPI and GraphQL support."),(0,r.kt)("p",null,"Server will listen to ",(0,r.kt)("inlineCode",{parentName:"p"},"http://127.0.0.1:3042")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "server": {\n "hostname": "127.0.0.1",\n "port": "3042"\n },\n "db": {\n "connectionString": "sqlite://./db.sqlite",\n "graphiql": true,\n "openapi": true,\n "graphql": true\n }\n}\n')))}c.isMDXComponent=!0}}]);
\ No newline at end of file
diff --git a/assets/js/01f06724.6b15f130.js b/assets/js/01f06724.6b15f130.js
new file mode 100644
index 00000000000..f1b57212876
--- /dev/null
+++ b/assets/js/01f06724.6b15f130.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[2137],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>g});var a=n(67294);function o(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 a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;tid = 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/03c08581.276e1e72.js b/assets/js/03c08581.276e1e72.js
new file mode 100644
index 00000000000..7bc7b0d9da6
--- /dev/null
+++ b/assets/js/03c08581.276e1e72.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[62654],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>k});var i=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 i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;tautoload
",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.8.1/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/03cb791b.a52d0e73.js b/assets/js/03cb791b.a52d0e73.js
new file mode 100644
index 00000000000..362ff92cf65
--- /dev/null
+++ b/assets/js/03cb791b.a52d0e73.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/045117ff.d11a7470.js b/assets/js/045117ff.d11a7470.js
new file mode 100644
index 00000000000..e875c20f088
--- /dev/null
+++ b/assets/js/045117ff.d11a7470.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[46766],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var a=n(67294);function i(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 a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;tconnect(opts) : Promise
",id:"connectopts--promise",level:3},{value:"createConnectionPool(opts) : Promise
",id:"createconnectionpoolopts--promise",level:3},{value:"Code samples",id:"code-samples",level:2}],c={toc:s},m="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(m,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"introduction-to-platformaticsql-mapper"},"Introduction to @platformatic/sql-mapper"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"@platformatic/sql-mapper")," is the underlining utility that Platformatic DB uses to create useful utilities to\nmanipulate your SQL database using JavaScript. "),(0,i.kt)("p",null,"This module is bundled with ",(0,i.kt)("a",{parentName:"p",href:"/docs/1.8.0/reference/db/introduction"},"Platformatic DB")," via ",(0,i.kt)("a",{parentName:"p",href:"/docs/1.8.0/reference/sql-mapper/fastify-plugin"},"a fastify plugin"),"\nThe rest of this guide shows how to use this module directly."),(0,i.kt)("h2",{id:"install"},"Install"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"npm i @platformatic/sql-mapper\n")),(0,i.kt)("h2",{id:"api"},"API"),(0,i.kt)("h3",{id:"connectopts--promise"},(0,i.kt)("inlineCode",{parentName:"h3"},"connect(opts) : Promise")),(0,i.kt)("p",null,"It will inspect a database schema and return an object containing:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"db")," \u2014 A database abstraction layer from ",(0,i.kt)("a",{parentName:"li",href:"https://www.atdatabases.org/"},(0,i.kt)("inlineCode",{parentName:"a"},"@databases"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"sql")," \u2014 The SQL builder from ",(0,i.kt)("a",{parentName:"li",href:"https://www.atdatabases.org/"},(0,i.kt)("inlineCode",{parentName:"a"},"@databases"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"entities")," \u2014 An object containing a key for each table found in the schema, with basic CRUD operations. See ",(0,i.kt)("a",{parentName:"li",href:"/docs/1.8.0/reference/sql-mapper/entities/introduction"},"Entity Reference")," for details.")),(0,i.kt)("p",null,"The valid options are:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"connectionString")," \u2014 The Database connection string"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"poolSize")," - Maximum number of connections in the connection pool. Defaults to ",(0,i.kt)("inlineCode",{parentName:"li"},"10"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"log")," \u2014 A logger object (like ",(0,i.kt)("a",{parentName:"li",href:"https://getpino.io"},"Pino"),")"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"onDatabaseLoad")," \u2014 An async function that is called after the connection is established. It will receive ",(0,i.kt)("inlineCode",{parentName:"li"},"db")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"sql")," as parameter."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"ignore")," \u2014 Object used to ignore some tables from building entities. (i.e. ",(0,i.kt)("inlineCode",{parentName:"li"},"{ 'versions': true }")," will ignore ",(0,i.kt)("inlineCode",{parentName:"li"},"versions")," table)"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"autoTimestamp")," \u2014 Generate timestamp automatically when inserting/updating records."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"hooks")," \u2014 For each entity name (like ",(0,i.kt)("inlineCode",{parentName:"li"},"Page"),") you can customize any of the entity API function. Your custom function will receive the original function as first parameter, and then all the other parameters passed to it."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"cache")," \u2014 enable cache and dedupe features - currently supported ",(0,i.kt)("inlineCode",{parentName:"li"},"dedupe")," on entities ",(0,i.kt)("inlineCode",{parentName:"li"},"find")," method only. Boolean, default is disabled.")),(0,i.kt)("h3",{id:"createconnectionpoolopts--promise"},(0,i.kt)("inlineCode",{parentName:"h3"},"createConnectionPool(opts) : Promise")),(0,i.kt)("p",null,"It will inspect a database schema and return an object containing:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"db")," \u2014 A database abstraction layer from ",(0,i.kt)("a",{parentName:"li",href:"https://www.atdatabases.org/"},(0,i.kt)("inlineCode",{parentName:"a"},"@databases"))),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"sql")," \u2014 The SQL builder from ",(0,i.kt)("a",{parentName:"li",href:"https://www.atdatabases.org/"},(0,i.kt)("inlineCode",{parentName:"a"},"@databases")))),(0,i.kt)("p",null,"The valid options are:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"connectionString")," \u2014 The Database connection string"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"poolSize")," - Maximum number of connections in the connection pool. Defaults to ",(0,i.kt)("inlineCode",{parentName:"li"},"10"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"log")," \u2014 A logger object (like ",(0,i.kt)("a",{parentName:"li",href:"https://getpino.io"},"Pino"),")")),(0,i.kt)("p",null,"This utility is useful if you just need to connect to the db without generating any entity."),(0,i.kt)("h2",{id:"code-samples"},"Code samples"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-javascript"},"const { connect } = require('@platformatic/sql-mapper')\nconst { pino } = require('pino')\n\nconst logger = pino()\n\nasync function onDatabaseLoad (db, sql) {\n await db.query(sql`CREATE TABLE pages (\n id SERIAL PRIMARY KEY,\n title VARCHAR(255) NOT NULL\n );`)\n}\nconst connectionString =\n 'postgres://postgres:postgres@localhost:5432/postgres'\nconst mapper = await connect({\n connectionString,\n log: logger,\n onDatabaseLoad,\n ignore: {},\n hooks: {\n Page: {\n find: async function(_find, opts) {\n console.log('hook called');\n return await _find(opts)\n }\n }\n },\n cache: true\n})\nconst pageEntity = mapper.entities.page\n\nawait mapper.db.query(mapper.sql`SELECT * FROM pages`)\nawait mapper.db.find('option1', 'option2')\n")))}d.isMDXComponent=!0}}]);
\ No newline at end of file
diff --git a/assets/js/04cbffa8.87c0c7a6.js b/assets/js/04cbffa8.87c0c7a6.js
new file mode 100644
index 00000000000..6a5ca31e6cb
--- /dev/null
+++ b/assets/js/04cbffa8.87c0c7a6.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[25971],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(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/0680a47f.61601743.js b/assets/js/0680a47f.61601743.js
new file mode 100644
index 00000000000..86bc074c5e2
--- /dev/null
+++ b/assets/js/0680a47f.61601743.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[97784],{3905:(e,n,r)=>{r.d(n,{Zo:()=>s,kt:()=>m});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function a(e){for(var n=1;nsqlite
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/06937cbf.9fb27856.js b/assets/js/06937cbf.9fb27856.js
new file mode 100644
index 00000000000..e182fa6aec4
--- /dev/null
+++ b/assets/js/06937cbf.9fb27856.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkplatformatic_oss_website=self.webpackChunkplatformatic_oss_website||[]).push([[3068],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});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 s(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;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