diff --git a/components/learn/pattern/CodeView.js b/components/learn/pattern/CodeView.js index 0dfd3c1cde0..adc1d485ba6 100644 --- a/components/learn/pattern/CodeView.js +++ b/components/learn/pattern/CodeView.js @@ -4,7 +4,7 @@ import { FaRegCopy, FaCheck } from 'react-icons/fa'; import styles from './CodeView.module.css'; import { useState } from 'react' -export default function Counter(props) { +export default function CodeView(props) { const [visible, setVisible] = useState(false); const [copied, setCopied] = useState(false); @@ -21,6 +21,7 @@ export default function Counter(props) { return (
+ {props.name &&
{props.name}
} codeCopy()}> { copied ? : diff --git a/components/learn/pattern/CodeView.module.css b/components/learn/pattern/CodeView.module.css index cf6b97315f9..5081ce29e10 100644 --- a/components/learn/pattern/CodeView.module.css +++ b/components/learn/pattern/CodeView.module.css @@ -22,3 +22,8 @@ .copied { color: #20b6b0; } + +.title { + font-size: 1rem; + color: gray; +} diff --git a/components/learn/pattern/readPattern.js b/components/learn/pattern/readPattern.js index af371de2a5b..ec00d784964 100644 --- a/components/learn/pattern/readPattern.js +++ b/components/learn/pattern/readPattern.js @@ -3,32 +3,50 @@ import fs from 'fs'; import { getHighlighter } from "shiki"; import { load } from "js-yaml"; + export async function readPattern(pattern) { const baseDirectory = path.resolve("pages/learn/enterprise-integration-patterns/enterprise-integration-patterns"); - const highlighter = await getHighlighter({ theme: 'github-light' }); const ymlPath = path.join(baseDirectory, pattern, pattern + ".yml"); - const source = fs.readFileSync(path.join(baseDirectory, pattern, pattern + ".bal"), "utf-8"); - const [header, main] = split(source); - const headerCode = header.length > 0 ? highlighter.codeToHtml(header, { lang: 'ballerina' }) : ""; - const mainCode = highlighter.codeToHtml(main, { lang: 'ballerina' }); - const name = pattern.replace(/-.|^./g, x => " " + x.slice(-1).toUpperCase()); if (!fs.existsSync(ymlPath)) { - return { props: { mainCode, headerCode, name } }; + return readPatternContent({}, pattern, [pattern + ".bal"]); } const yml = fs.readFileSync(ymlPath, "utf-8"); - var patternProps = load(yml) || {}; - patternProps.headerCode = headerCode; - patternProps.mainCode = mainCode; - patternProps.name = patternProps.name ?? name; - patternProps.raw = source; - return { props: patternProps }; + var loadedProps = load(yml) || {}; + return readPatternContent(loadedProps, pattern, loadedProps.files || [pattern + ".bal"]); +} + + async function readPatternContent(loadedProps, pattern, files) { + const name = pattern.replace(/-.|^./g, x => " " + x.slice(-1).toUpperCase()); + const baseDirectory = path.resolve("pages/learn/enterprise-integration-patterns/enterprise-integration-patterns"); + loadedProps.content = []; + for (let i = 0; i < files.length; i++) { + const file = files[i]; + const filePath = path.join(baseDirectory, pattern, file); + const content = fs.readFileSync(filePath, "utf-8"); + const [header, main] = split(content); + const headerCode = await highlight(header); + const mainCode = await highlight(main); + loadedProps.content.push({ headerCode, mainCode, raw: content, name: file }); + } + loadedProps.name = loadedProps.name ?? name; + return { props: loadedProps }; } +const regex = /\n(service|function|public function)/g; + function split(content){ - const regex = /\n(service|function|public function)/g; const i = content.search(regex); if(i < 80) { return ["", content]; } return [content.slice(0, i), content.slice(i)]; } + +const highlighterPromise = getHighlighter({ theme: 'github-light' }); + +async function highlight(src){ + if (!src) { + return ""; + } + return (await highlighterPromise).codeToHtml(src, { lang: 'ballerina' }); +} diff --git a/pages/learn/enterprise-integration-patterns/[pattern].js b/pages/learn/enterprise-integration-patterns/[pattern].js index 54f696d2ea2..3a32da6f549 100644 --- a/pages/learn/enterprise-integration-patterns/[pattern].js +++ b/pages/learn/enterprise-integration-patterns/[pattern].js @@ -34,7 +34,7 @@ import CodeView from '../../../components/learn/pattern/CodeView'; import { readPattern } from '../../../components/learn/pattern/readPattern'; export async function getStaticProps({ params }) { - return readPattern(params.pattern); + return await readPattern(params.pattern); } const baseDirectory = path.resolve("pages/learn/enterprise-integration-patterns/enterprise-integration-patterns"); @@ -46,8 +46,9 @@ export async function getStaticPaths() { const file = files[i]; const filePath = path.join(baseDirectory, file); const stats = fs.statSync(filePath); - const bal = path.join(filePath, file + ".bal"); - if (stats.isDirectory() && fs.existsSync(bal)) { + const balPath = path.join(filePath, file + ".bal"); + const ymlPath = path.join(baseDirectory, file, file + ".yml"); + if (stats.isDirectory() && (fs.existsSync(balPath) || fs.existsSync(ymlPath))) { paths.push({ params: { pattern: file } }); } } @@ -55,7 +56,21 @@ export async function getStaticPaths() { } export default function Pattern(props) { - const router = useRouter(); + const rows = []; + const content = props.content; + const namedCodeViews = content.length > 1; + for (let i = 0; i < content.length; i++) { + const row = content[i]; + rows.push( + + + + + + + + ); + } return ( <> @@ -198,13 +213,7 @@ export default function Pattern(props) { - - - - - - - + {rows} diff --git a/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/claim-check/claim-check.yml b/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/claim-check/claim-check.yml index ba8d71995ab..43b22e9826e 100644 --- a/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/claim-check/claim-check.yml +++ b/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/claim-check/claim-check.yml @@ -2,6 +2,7 @@ tagline: Reduce message volume and send across the system without losing message desc: Claim Check will store messages in a persistent storage and send a claim to another application to access the origin stored message. category: Message Transformation index: 39 -helps: +helps: Ballerina supports the persistent storage of messages. Popular storage technologies such as SQL, AWS S3 and Redis are available as Ballerina packages. tags: ["Claim Check", "Content Enricher", "Content Filter"] link: https://www.enterpriseintegrationpatterns.com/patterns/messaging/StoreInLibrary.html +files: ["claim-check-consumer.bal", "claim-check-producer.bal"] diff --git a/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/publish-subscribe-channel/publish-subscribe-channel.yml b/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/publish-subscribe-channel/publish-subscribe-channel.yml index 4b18fcffdb4..3ec17e3d627 100644 --- a/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/publish-subscribe-channel/publish-subscribe-channel.yml +++ b/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/publish-subscribe-channel/publish-subscribe-channel.yml @@ -1,3 +1,9 @@ +name: Publish-Subscribe Channel category: Messaging Channels +tagline: Delivers a copy of a particular event to each receiver index: 7 +desc: Publish-Subscribe Channel delivers a copy of a particular event to each receiver. +helps: Ballerina has a rich set of libraries to interact with various messaging protocols. These include protocols that support publish-subscribe semantics such as Kafka, MQTT, and WebSocket. +tags: ["Publish-Subscribe Channel", "Message Channel", "Message Endpoint", "Message Router"] link: https://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html +files: ["publisher.bal", "subscriber.bal"] diff --git a/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/routing-slip/routing-slip.yml b/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/routing-slip/routing-slip.yml index 5c8ffef0a80..96563ffc7ec 100644 --- a/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/routing-slip/routing-slip.yml +++ b/pages/learn/enterprise-integration-patterns/enterprise-integration-patterns/routing-slip/routing-slip.yml @@ -5,3 +5,4 @@ index: 33 helps: Ballerina excels in enabling the seamless integration of diverse services with inherent concurrent support, as well as in data binding, type enforcement, and native error-handling capabilities. tags: ["Routing Slip", "Message Channel", "Message Endpoint", "Message Router"] link: https://www.enterpriseintegrationpatterns.com/patterns/messaging/RoutingTable.html +files: ["routing-slip-main.bal", "loyalty-point-service.bal"] diff --git a/pages/learn/enterprise-integration-patterns/index.js b/pages/learn/enterprise-integration-patterns/index.js index ee992a200d9..a7f9117ca40 100644 --- a/pages/learn/enterprise-integration-patterns/index.js +++ b/pages/learn/enterprise-integration-patterns/index.js @@ -36,11 +36,11 @@ export async function getStaticProps() { const file = files[i]; const filePath = path.join(baseDirectory, file); const stats = fs.statSync(filePath); - const bal = path.join(filePath, file + ".bal"); - if (!stats.isDirectory() || !fs.existsSync(bal)) { + const balPath = path.join(filePath, file + ".bal"); + const ymlPath = path.join(baseDirectory, file, file + ".yml"); + if (!stats.isDirectory() || !(fs.existsSync(balPath) || fs.existsSync(ymlPath))) { continue; } - const ymlPath = path.join(baseDirectory, file, file + ".yml"); const name = file.replace(/-.|^./g, x => " " + x.slice(-1).toUpperCase()).trim(); var pattern = loadYml(ymlPath) || {}; pattern.name = pattern.name ?? name; diff --git a/public/images/data-service-guide-output.png b/public/images/data-service-guide-output.png new file mode 100644 index 00000000000..cbea541052a Binary files /dev/null and b/public/images/data-service-guide-output.png differ diff --git a/public/images/patterns/claim-check.svg b/public/images/patterns/claim-check.svg new file mode 100644 index 00000000000..41d0b78f6ab --- /dev/null +++ b/public/images/patterns/claim-check.svg @@ -0,0 +1,2 @@ + + diff --git a/public/images/patterns/publish-subscribe-channel.svg b/public/images/patterns/publish-subscribe-channel.svg new file mode 100644 index 00000000000..d9735220f88 --- /dev/null +++ b/public/images/patterns/publish-subscribe-channel.svg @@ -0,0 +1,2 @@ + + diff --git a/swan-lake/integration-tools/edi-tool.md b/swan-lake/integration-tools/edi-tool.md index 3b39d1ae858..6bf37693bea 100644 --- a/swan-lake/integration-tools/edi-tool.md +++ b/swan-lake/integration-tools/edi-tool.md @@ -138,7 +138,7 @@ Follow the steps below to try out an example of generating Ballerina code from a ```ballerina import ballerina/io; - + public function main() returns error? { string ediText = check io:fileReadString("resources/edi-sample.edi"); SimpleOrder newOrder = check hmartOrder:fromEdiString(ediText); @@ -148,22 +148,23 @@ Follow the steps below to try out an example of generating Ballerina code from a 4. Use the generated `toEdiString` function to serialize the `SimpleOrder` records into EDI text, as shown below. -```ballerina -import test_edi.hmartOrder; -import ballerina/io; + ```ballerina + import test_edi.hmartOrder; -public function main() returns error? { - hmartOrder:SimpleOrder salesOrder = {header: {orderId: "ORDER_200", organization: "HMart", date: "17-05-2023"}}; - salesOrder.items.push({item: "A680", quantity: 15}); - salesOrder.items.push({item: "A530", quantity: 2}); - salesOrder.items.push({item: "A500", quantity: 4}); + import ballerina/io; -string orderEDI = check hmartOrder:toEdiString(salesOrder); -io:println (orderEDI); -} -``` + public function main() returns error? { + hmartOrder:SimpleOrder salesOrder = {header: {orderId: "ORDER_200", organization: "HMart", date: "17-05-2023"}}; + salesOrder.items.push({item: "A680", quantity: 15}); + salesOrder.items.push({item: "A530", quantity: 2}); + salesOrder.items.push({item: "A500", quantity: 4}); + + string orderEDI = check hmartOrder:toEdiString(salesOrder); + io:println(orderEDI); + } + ``` -Below is the EDI document generated as the output of the above Ballerina code that can be parsed using the above schema. + Below is the EDI document that gets generated as the output of the above Ballerina code that can be parsed using the above schema. ``` HDRORDER_200HMart17-05-2023~ @@ -174,123 +175,100 @@ Below is the EDI document generated as the output of the above Ballerina code th ### Package generation example -Follow the steps below to try out an example package generation use case of the EDI tool. - -#### Clone the sample project +Below is an example of creating an EDI package and using it. -Clone the [artifacts of the example](https://github.com/ballerina-guides/integration-samples/edi_package_generation/) and extract them to a preferred location. +#### Create the package ->**Info:** The cloned directory includes the artifacts that will be required to try out this example. The `schemas` folder includes the schemas of the `EDIFACT` specifications required for an organization (`CityMart`) to work with the `INVOICE`, `ORDERS`, and `ORDRSP` EDI operations for handling purchase orders. Also, the `main.bal` file, which gets generated by the EDI tool includes the business logic/usage of the package. +If an organization (`CityMart`) needs to work with `X12 850`, `810`, `820`, and `855` for handling purchase orders, then, its integration developers can put schemas of those `X12` specifications into a folder as follows. -#### Generate the package - -Follow the steps below to run the EDI tool and create the Ballerina package. - -1. Navigate to the `edi_package_generation` directory. - -2. Run the tool with the [required arguments](#command-options) to generate the package. - - >**Note:** This example uses the EDI schema files of the [`edi_package_generation` example](https://github.com/ballerina-guides/integration-samples/edi_package_generation/) to generate the package. - - - ``` - $ bal edi libgen -O citymart -n porder -s CityMart/schemas -o CityMart/lib - ``` - - The generated Ballerina package will be, as shown below. +``` +|-- CityMart + |--lib + |--schemas + |--850.json + |--810.json + |--820.json + |--855.json +``` - >**Info:** The code for each EDI schema is generated into a separate module to prevent possible conflicts. +Execute the `libgen` command to generate a Ballerina package, as shown below. - ``` - |-- CityMart - |--lib - |--porder - | |--modules - | | |--m850 - | | | |--G_850.bal - | | | |--transformer.bal - | | |--m810 - | | | |--G_810.bal - | | | |--transformer.bal - | | |--m820 - | | | |--G_820.bal - | | | |--transformer.bal - | | |--m855 - | | |--G_855.bal - | | |--transformer.bal - | |--Ballerina.toml - | |--Module.md - | |--Package.md - | |--porder.bal - | |--rest_connector.bal - | - |--schemas - |--850.json - |--810.json - |--820.json - |--855.json - ``` - -3. Build the generated package. +``` +$ bal edi libgen -O citymart -n porder -s CityMart/schemas -o CityMart/lib +``` - ``` - $ cd edi_package_generation - $ bal pack - ``` +The generated Ballerina package will be, as shown below. -4. Push it to a repository. +``` +|-- CityMart + |--lib + |--porder + | |--modules + | | |--m850 + | | | |--G_850.bal + | | | |--transformer.bal + | | |--m810 + | | | |--G_810.bal + | | | |--transformer.bal + | | |--m820 + | | | |--G_820.bal + | | | |--transformer.bal + | | |--m855 + | | |--G_855.bal + | | |--transformer.bal + | |--Ballerina.toml + | |--Module.md + | |--Package.md + | |--porder.bal + | |--rest_connector.bal + | + |--schemas + |--850.json + |--810.json + |--820.json + |--855.json +``` - >**Tip:** You can push either to the local repository or the remote repository in Ballerina Central. +As seen in the above project structure, the code for each EDI schema is generated into a separate module to prevent possible conflicts. Now, it is possible to build the above project using the `bal pack` command and publish it into [Ballerina Central](https://central.ballerina.io/) using the `bal push` command. - ``````` - $ bal push --repository local - ```` +Then, any Ballerina project can import this package and use it to work with the EDI files related to purchase orders. An example of using this package for reading an `850` file and writing an `855` file is shown below. -#### Use the generated package +```ballerina +import ballerina/io; +import citymart/porder.m850; +import citymart/porder.m855; +public function main() returns error? { + string orderText = check io:fileReadString("orders/d15_05_2023/order10.edi"); + m850:Purchase_Order purchaseOrder = check m850:fromEdiString(orderText); + ... + m855:Purchase_Order_Acknowledgement orderAck = {...}; + string orderAckText = check m855:toEdiString(orderAck); + check io:fileWriteString("acks/d15_05_2023/ack10.edi", orderAckText); +} +``` It is quite common for different trading partners to use variations of the standard EDI formats. In such cases, it is possible to create partner-specific schemas and generate a partner-specific Ballerina package for processing interactions with a particular partner. -Follow the steps below to use the generated package by running the cloned Ballerina project. - ->**Info:** Now, any Ballerina project can import this package and use it to work with the EDI files related to purchase orders. An example of using this package for reading an `ORDERS` file and writing an `INVOIC` file is shown below. - -1. Navigate to the `edi_package-generation` directory. - - >**Info:** You can change the dependency (name and version) of the generated package in the `Ballerina.toml` file of this cloned Ballerina project directory as preferred. +You can convert `X12 850` EDI text to JSON using a cURL command, as shown below. - -2. Run the cloned Ballerina project and validate the output. - - ``` - $ bal run - Compiling source - healthcare_samples/carinbb_ballerina:1.0.0 - - Running executable - ``` - -3. Invoke the API to try it out. - - >**Info:** You can convert `X12 850` EDI text to JSON using a cURL command, as shown below. - - ``` - $curl --request POST \ - --url http://localhost:9090/porderParser/edis/850 \ - --header 'Content-Type: text/plain' \ - --data 'ST*834*12345*005010X220A1~ - BGN*00*12456*20020601*1200****~ - REF*38*ABCD012354~ - AMT*cc payment*467.34*~ - N1*P5**FI*999888777~ - N1*IN**FI*654456654~ - INS*Y*18*025**A***FT~ - REF*0F*202443307~ - REF*1L*123456001~ - NM1*IL*1*SMITH*WILLIAM****ZZ*202443307~ - HD*025**DEN~ - DTP*348*D8*20020701~ - SE*12*12345~' - ``` +``` +$curl --request POST \ + --url http://localhost:9090/porderParser/edis/850 \ + --header 'Content-Type: text/plain' \ + --data 'ST*834*12345*005010X220A1~ +BGN*00*12456*20020601*1200****~ +REF*38*ABCD012354~ +AMT*cc payment*467.34*~ +N1*P5**FI*999888777~ +N1*IN**FI*654456654~ +INS*Y*18*025**A***FT~ +REF*0F*202443307~ +REF*1L*123456001~ +NM1*IL*1*SMITH*WILLIAM****ZZ*202443307~ +HD*025**DEN~ +DTP*348*D8*20020701~ +SE*12*12345~' +``` The above REST call will return a JSON response, as shown below. @@ -418,4 +396,4 @@ The above REST call will return a JSON response, as shown below. The EDI package generated above can also be compiled into a JAR file (using the `bal build` command) and executed as a standalone Ballerina service that processes EDI files via a REST interface. This is useful for microservices environments where the EDI processing functionality can be deployed as a separate microservice. -For example, the `citymart` package generated above can be built and executed as a JAR file. Once executed, it will expose a REST service to work with the `INVOICE`, `ORDERS`, and `ORDRSP` files. +For example, the `citymart` package generated above can be built and executed as a JAR file. Once executed, it will expose a REST service to work with `X12 850`, `810`, `820`, and `855` files. \ No newline at end of file diff --git a/swan-lake/resources/featured-scenarios/build-a-data-service-in-ballerina.md b/swan-lake/resources/featured-scenarios/build-a-data-service-in-ballerina.md index 446f7c9940f..6adfd4691a3 100644 --- a/swan-lake/resources/featured-scenarios/build-a-data-service-in-ballerina.md +++ b/swan-lake/resources/featured-scenarios/build-a-data-service-in-ballerina.md @@ -459,6 +459,13 @@ $ bal run You view the output below. +``` +Compiling source + foo/data_service:0.1.0 + +Running executable +``` + >**Info:** This creates an `/employees` endpoint on port `8080`, which can be accessed via a browser by visiting `http://locahost:8080/employees`. @@ -467,24 +474,13 @@ be accessed via a browser by visiting `http://locahost:8080/employees`. Invoke the defined resource method by sending the `POST` request below to `http://localhost:8080/employees` with the required data as a JSON payload. ``` -$ curl -X POST http://localhost:8080/employees/ - -H 'Content-Type: application/json' - -d '{ - "employee_id": 6, - "first_name": "test", - "last_name": "test", - "email": "test@test.com", - "phone": "882 771 110", - "hire_date": { - "year": 2021, - "month": 12, - "day": 16 - }, - "manager_id": 1, - "job_title": "Sales Manager" - }' +curl -X POST http://localhost:8080/employees/ -H "Content-Type: application/json" -d "{ \"employee_id\": 6, \"first_name\": \"test\", \"last_name\": \"test\", \"email\": \"test@test.com\", \"phone\": \"882 771 110\", \"hire_date\": { \"year\": 2021, \"month\": 12, \"day\": 16 }, \"manager_id\": 1, \"job_title\": \"Sales Manager\" }" ``` +You view a row added to the **Employees** table as shown below. + +![data service output](/images/data-service-guide-output.png) + ## Learn more To learn more about MySQL and HTTP support in Ballerina, see the following: diff --git a/swan-lake/resources/featured-scenarios/manage-data-persistence-with-bal-persist.md b/swan-lake/resources/featured-scenarios/manage-data-persistence-with-bal-persist.md index 048af0b2406..f263ff231ab 100644 --- a/swan-lake/resources/featured-scenarios/manage-data-persistence-with-bal-persist.md +++ b/swan-lake/resources/featured-scenarios/manage-data-persistence-with-bal-persist.md @@ -473,20 +473,7 @@ Running executable Invoke the defined resource method by sending the POST request below to http://localhost:8080/employees with the required data as a JSON payload. ``` -$ curl -X POST http://localhost:8080/employees/ - -H 'Content-Type: application/json' - -d '{ - "id": "6", - "firstName": "test", - "lastName": "test", - "email": "test@test.com", - "phone": "882 771 110", - "hireDate": { - "year": 2021, - "month": 12, - "day": 16 - }, - "managerId": "mng_01", - "jobTitle": "Sales Manager" - }' +curl -X POST http://localhost:8080/employees/ -H "Content-Type: application/json" -d "{ \"id\": \"6\", \"firstName\": \"test\", \"lastName\": \"test\", \"email\": \"test@test.com\", \"phone\": \"882 771 110\", \"hireDate\": { \"year\": 2021, \"month\": 12, \"day\": 16 }, \"managerId\": \"1\", \"jobTitle\": \"Sales Manager\" }" ``` + +The entered employee ID `6` will be returned as the response. diff --git a/swan-lake/resources/featured-scenarios/write-a-graphql-api-with-ballerina.md b/swan-lake/resources/featured-scenarios/write-a-graphql-api-with-ballerina.md index 0f4f729da1f..de6f2923b28 100644 --- a/swan-lake/resources/featured-scenarios/write-a-graphql-api-with-ballerina.md +++ b/swan-lake/resources/featured-scenarios/write-a-graphql-api-with-ballerina.md @@ -421,7 +421,7 @@ type Mutation { Execute the cURL command below to retrieve all the data from the endpoint. ``` -$ curl -X POST -H "Content-type: application/json" -H "scope: unknown" -d '{ "query": "query { all { country cases active} }" }' 'http://localhost:9000/covid19' +curl -X POST -H "Content-type: application/json" -H "scope: unknown" -d "{ \"query\": \"query { all { country cases active} }\" }" http://localhost:9000/covid19 ``` In this request: diff --git a/swan-lake/resources/featured-scenarios/write-a-restful-api-with-ballerina.md b/swan-lake/resources/featured-scenarios/write-a-restful-api-with-ballerina.md index 8cdbda2a99d..11fc5375715 100644 --- a/swan-lake/resources/featured-scenarios/write-a-restful-api-with-ballerina.md +++ b/swan-lake/resources/featured-scenarios/write-a-restful-api-with-ballerina.md @@ -328,7 +328,7 @@ In another terminal, execute the cURL commands below one by one to try out the s Execute the cURL command below. ``` -$ curl http://localhost:9000/covid/status/countries +curl http://localhost:9000/covid/status/countries ``` You view the output below. @@ -342,7 +342,7 @@ You view the output below. Execute the cURL command below. ``` -$ curl http://localhost:9000/covid/status/countries -d "[{\"iso_code\":\"DEU\", \"country\":\"Germany\", \"cases\":159333, \"deaths\":7390, \"recovered\":126084, \"active\":6833}]" -H "Content-Type: application/json" +curl http://localhost:9000/covid/status/countries -d "[{\"iso_code\":\"DEU\", \"country\":\"Germany\", \"cases\":159333, \"deaths\":7390, \"recovered\":126084, \"active\":6833}]" -H "Content-Type: application/json" ``` You view the output below. @@ -356,7 +356,7 @@ You view the output below. Execute the cURL command below. ``` -$ curl http://localhost:9000/covid/status/countries/AFG +curl http://localhost:9000/covid/status/countries/AFG ``` You view the output below.