PageSourceSearch

https://vulcansql.com/assets/js/793fa1e2.66c0260d.js

js vulcansql.com collected 2026-10-03 23:20:06 UTC 13,327 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkdoc=self.webpackChunkdoc||[]).push([[8032],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var a=n(7294);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 l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),u=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=u(n),h=r,m=d["".concat(s,".").concat(h)]||d[h]||p[h]||i;return n?a.createElement(m,l(l({ref:t},c),{},{components:n})):a.createElement(m,l({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,l=new Array(i);l[0]=d;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:r,l[1]=o;for(var u=2;u<i;u++)l[u]=n[u];return a.createElement.apply(null,l)}return a.createElement.apply(null,n)}d.displayName="MDXCreateElement"},5162:(e,t,n)=>{n.d(t,{Z:()=>l});var a=n(7294),r=n(6010);const i="tabItem_Ymn6";function l(e){let{children:t,hidden:n,className:l}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(i,l),hidden:n},t)}},5488:(e,t,n)=>{n.d(t,{Z:()=>h});var a=n(7462),r=n(7294),i=n(6010),l=n(2389),o=n(7392),s=n(7094),u=n(2466);const c="tabList__CuJ",p="tabItem_LNqP";function d(e){var t;const{lazy:n,block:l,defaultValue:d,values:h,groupId:m,className:f}=e,g=r.Children.map(e.children,(e=>{if((0,r.isValidElement)(e)&&"value"in e.props)return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})),y=h??g.map((e=>{let{props:{value:t,label:n,attributes:a}}=e;return{value:t,label:n,attributes:a}})),k=(0,o.l)(y,((e,t)=>e.value===t.value));if(k.length>0)throw new Error(`Docusaurus error: Duplicate values "${k.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`);const b=null===d?d:d??(null==(t=g.find((e=>e.props.default)))?void 0:t.props.value)??g[0].props.value;if(null!==b&&!y.some((e=>e.value===b)))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${b}" but none of its children has the corresponding value. Available values are: ${y.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);const{tabGroupChoices:w,setTabGroupChoices:v}=(0,s.U)(),[N,C]=(0,r.useState)(b),T=[],{blockElementScrollPositionUntilNextRender:q}=(0,u.o5)();if(null!=m){const e=w[m];null!=e&&e!==N&&y.some((t=>t.value===e))&&C(e)}const O=e=>{const t=e.currentTarget,n=T.indexOf(t),a=y[n].value;a!==N&&(q(t),C(a),null!=m&&v(m,String(a)))},I=e=>{var t;let n=null;switch(e.key){case"ArrowRight":{const t=T.indexOf(e.currentTarget)+1;n=T[t]??T[0];break}case"ArrowLeft":{const t=T.indexOf(e.currentTarget)-1;n=T[t]??T[T.length-1];break}}
1null==(t=n)||t.focus()};return r.createElement("div",{className:(0,i.Z)("tabs-container",c)},r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":l},f)},y.map((e=>{let{value:t,label:n,attributes:l}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:N===t?0:-1,"aria-selected":N===t,key:t,ref:e=>T.push(e),onKeyDown:I,onFocus:O,onClick:O},l,{className:(0,i.Z)("tabs__item",p,null==l?void 0:l.className,{"tabs__item--active":N===t})}),n??t)}))),n?(0,r.cloneElement)(g.filter((e=>e.props.value===N))[0],{className:"margin-top--md"}):r.createElement("div",{className:"margin-top--md"},g.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==N})))))}function h(e){const t=(0,l.Z)();return r.createElement(d,(0,a.Z)({key:String(t)},e))}},7289:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>u,toc:()=>p});var a=n(7462),r=(n(7294),n(3905)),i=n(5488),l=n(5162);const o={},s="Create Your First Data API",u={unversionedId:"get-started/first-api",id:"get-started/first-api",title:"Create Your First Data API",description:"In this tutorial, you will learn how to create an data API server with SQL using VulcanSQL. Make sure you have followed the installation guide to install the VulcanSQL CLI before proceeding.",source:"@site/docs/get-started/first-api.mdx",sourceDirName:"get-started",slug:"/get-started/first-api",permalink:"/docs/get-started/first-api",draft:!1,editUrl:"https://github.com/Canner/vulcan-sql/tree/main/packages/doc/docs/get-started/first-api.mdx",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Installation",permalink:"/docs/get-started/installation"},next:{title:"Initializing Your Project",permalink:"/docs/develop/init"}},c={},p=[{value:"Step 1: Initializing Your Quick-Start Project",id:"step-1-initializing-your-quick-start-project",level:2},{value:"Step 2: Creating a New API Endpoint",id:"step-2-creating-a-new-api-endpoint",level:2},{value:"Step 3: Test the New API Endpoint",id:"step-3-test-the-new-api-endpoint",level:2},{value:"Step 4: Try Out Your Use Cases or Check Out Our Curated Examples",id:"step-4-try-out-your-use-cases-or-check-out-our-curated-examples",level:2}],d={toc:p};function h(e){let{components:t,...o}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"create-your-first-data-api"},"Create Your First Data API"),(0,r.kt)("p",null,"In this tutorial, you will learn how to create an data API server with SQL using VulcanSQL. Make sure you have followed the ",(0,r.kt)("a",{parentName:"p",href:"./installation"},"installation guide")," to install the VulcanSQL CLI before proceeding."),(0,r.kt)("h2",{id:"step-1-initializing-your-quick-start-project"},"Step 1: Initializing Your Quick-Start Project"),(0,r.kt)("p",null,"The following steps will differ depending on your installation method:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"If you installed VulcanSQL CLI ",(0,r.kt)("a",{parentName:"li",href:"./installation#install-from-npm"},"from NPM"),", select ",(0,r.kt)("inlineCode",{parentName:"li"},"NodeJS Project")),(0,r.kt)("li",{parentName:"ul"},"If you installed VulcanSQL CLI ",(0,r.kt)("a",{parentName:"li",href:"./installation#install-from-binary"},"from a binary"),", select ",(0,r.kt)("inlineCode",{parentName:"li"},"Binary"))),(0,r.kt)(i.Z,{groupId:"install-method",mdxType:"Tabs"},(0,r.kt)(l.Z,{value:"binary",label:"Binary",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"vulcan hello\n"))),(0,r.kt)(l.Z,{value:"nodejs",label:"NodeJS Project",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"vulcan init --template=quick-start-from-nodejs\n")))),(0,r.kt)("p",null,"  Once the quick-start project is initialized, start the server with the following command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"vulcan start --watch\n")),(0,r.kt)("p",null,"  In this quick-start project, we query the flights data from a CSV file with DuckDB. To test the API endpoint, try the following query in your browser or with curl:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"curl http://localhost:3000/api/flights\n")),(0,r.kt)("p",null,"  You should see the response:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'[\n  {\n    "FlightDate": "1988-01-01T00:00:00.000Z",\n    "UniqueCarrier": "AA",\n    "OriginCityName": "New York, NY",\n    "DestCityName": "Los Angeles, CA"\n  },\n  {\n    "FlightDate": "1988-01-02T00:00:00.000Z",\n    "UniqueCarrier": "AA",\n    "OriginCityName": "New York, NY",\n    "DestCityName": "Los Angeles, CA"\n  },\n  {\n    "FlightDate": "1988-01-03T00:00:00.000Z",\n    "UniqueCarrier": "BB",\n    "OriginCityName": "New York, NY",\n    "DestCityName": "Taipei, TW"\n  },\n  {\n    "FlightDate": "1988-01-04T00:00:00.000Z",\n    "UniqueCarrier": "CC",\n    "OriginCityName": "New York, NY",\n    "DestCityName": "Taipei, TW"\n  },\n  {\n    "FlightDate": "1988-01-04T00:00:00.000Z",\n    "UniqueCarrier": "CC",\n    "OriginCityName": "Los Angeles, CA",\n    "DestCityName": "Taipei, TW"\n  }\n]\n')),(0,r.kt)("p",null,"You can also open the API documentation in your browser by going to ",(0,r.kt)("a",{parentName:"p",href:"http://localhost:3000/doc"},"http://localhost:3000/doc")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"the screenshot of VulcanSQL API document",src:n(5024).Z,width:"1840",height:"621"})),(0,r.kt)("h2",{id:"step-2-creating-a-new-api-endpoint"},"Step 2: Creating a New API Endpoint"),(0,r.kt)("p",null,"In this step, we will create a new API endpoint to query flights with a specific ",(0,r.kt)("inlineCode",{parentName:"p"},"UniqueCarrier"),". Create a new file ",(0,r.kt)("inlineCode",{parentName:"p"},"sqls/flight.sql")," with the following content:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql",metastring:'title="sqls/flight.sql"',title:'"sqls/flight.sql"'},"SELECT * FROM read_csv_auto('flights.csv')\n  where UniqueCarrier= {{ context.params.UniqueCarrier | is_required }}\n")),(0,r.kt)("p",null,"In the above query:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"read_csv_auto")," is a duckdb built-in function to read CSV file."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"{{ context.params.UniqueCarrier | is_required }}")," is a VulcanSQL syntax that will be replaced with the actual value in the query. Additionally, with ",(0,r.kt)("inlineCode",{parentName:"li"},"is_required")," filter, we can ensure the ",(0,r.kt)("inlineCode",{parentName:"li"},"UniqueCarrier")," parameter is required.")),(0,r.kt)("p",null,"Next, create another file named ",(0,r.kt)("inlineCode",{parentName:"p"},"sqls/flight.yaml")," with the following content. This YAML file defines the API endpoint, specifies the URL path, and specifies which database profile to use."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="sqls/flight.yaml"',title:'"sqls/flight.yaml"'},"urlPath: /flight\nprofiles:\n  - duckdb\n")),(0,r.kt)("h2",{id:"step-3-test-the-new-api-endpoint"},"Step 3: Test the New API Endpoint"),(0,r.kt)("p",null,"Try the following query in your browser or with curl."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"curl http://localhost:3000/api/flight?UniqueCarrier=AA\n")),(0,r.kt)("p",null,"You should see the following response."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'[\n  {\n    "FlightDate": "1988-01-01T00:00:00.000Z",\n    "UniqueCarrier": "AA",\n    "OriginCityName": "New York, NY",\n    "DestCityName": "Los Angeles, CA"\n  },\n  {\n    "FlightDate": "1988-01-02T00:00:00.000Z",\n    "UniqueCarrier": "AA",\n    "OriginCityName": "New York, NY",\n    "DestCityName": "Los Angeles, CA"\n  }\n]\n')),(0,r.kt)("p",null,"Congratulations! You have successfully created a new API endpoint to query flights with a specific ",(0,r.kt)("inlineCode",{parentName:"p"},"UniqueCarrier"),". You can modify the query and the URL path to suit your specific needs."),(0,r.kt)("h2",{id:"step-4-try-out-your-use-cases-or-check-out-our-curated-examples"},"Step 4: Try Out Your Use Cases or Check Out Our Curated Examples"),(0,r.kt)("p",null,"Thank you once again for making it this far! We're certain you now have a good sense of how to create APIs with ease using VulcanSQL.\nWe encourage you to explore your own use cases and feel free to refer to the other sections of our documentation for additional guidance.\nIf you're finding it difficult to come up with ideas, no worries! We've put together ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/Canner/vulcan-sql-examples"},"a selection of examples"),"\nfor you to explore and we regularly update with new content."))}h.isMDXComponent=!0},5024:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/doc-screenshot-6eb5a055895397523a635f34c8b76f89.png"}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.