diff --git a/components/MDX.js b/components/MDX.js index 168e6c8dfb7..8b0be84e989 100644 --- a/components/MDX.js +++ b/components/MDX.js @@ -60,9 +60,14 @@ export function getMDXComponents() { th: props => , tr: props => , td: props => , - pre: props =>
, - inlineCode: props => , - code: CodeComponent, + pre: props => CodeComponent(props.children.props), + code: props => , + details: (props) => +
, + summary: (props) => + , + p: (props) => +

, hr: props =>


, CodeBlock, ChapterSuggestions, diff --git a/components/buttons/ScrollButton.js b/components/buttons/ScrollButton.js index 21920bbfe57..84671aa5989 100644 --- a/components/buttons/ScrollButton.js +++ b/components/buttons/ScrollButton.js @@ -23,7 +23,7 @@ function ScrollButton(){ }) } - return
+ return
{backToTopButton &&( )} diff --git a/components/navigation/MobileNavMenu.js b/components/navigation/MobileNavMenu.js index adcfe3424e5..2721323089f 100644 --- a/components/navigation/MobileNavMenu.js +++ b/components/navigation/MobileNavMenu.js @@ -9,7 +9,7 @@ import Link from 'next/link'; export default function MobileNavMenu({ onClickClose = () => {} }) { return ( -
+
diff --git a/components/navigation/NavBar.js b/components/navigation/NavBar.js index dd9dcbe3574..fa5f55f59b9 100644 --- a/components/navigation/NavBar.js +++ b/components/navigation/NavBar.js @@ -9,7 +9,6 @@ import LearningPanel from './LearningPanel' import CommunityPanel from "./CommunityPanel" import MobileNavMenu from './MobileNavMenu' import otherItems from './otherItems' - import GithubButton from "../buttons/GithubButton" import { SearchButton } from '../AlgoliaSearch'; import IconLoupe from '../icons/Loupe'; @@ -100,7 +99,7 @@ export default function NavBar({ useEffect(() => { setMobileMenuOpen(false); setOpen(null); - }, [asPath]) + }, [asPath]); return (
diff --git a/config/meetings.json b/config/meetings.json index 7e7bbe39f11..5d96773153e 100644 --- a/config/meetings.json +++ b/config/meetings.json @@ -1,11 +1,4 @@ [ - { - "title": "Spec 3.0 Docs Meeting", - "calLink": "https://www.google.com/calendar/event?eid=aHJwdnA1bzI1ajVjNzliZ2h2bm1nZnI3b3MgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/793", - "banner": "", - "date": "2023-08-31T14:30:00.000Z" - }, { "title": "Spec 3.0 Meeting", "calLink": "https://www.google.com/calendar/event?eid=NDEzM2E1ZGE5YWttYXVpYW9zbTl1cWM1YWMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", @@ -13,13 +6,6 @@ "banner": "", "date": "2023-09-06T16:00:00.000Z" }, - { - "title": "AsyncAPI spec v3 support in Diff", - "calLink": "https://www.google.com/calendar/event?eid=YnVvZWt1azlwcTQxNzZnNzNpZ2c3cjdmbzAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/858", - "banner": "", - "date": "2023-08-29T13:30:00.000Z" - }, { "title": "Brainstorm on AsyncAPI Cheat Sheet Poster", "calLink": "https://www.google.com/calendar/event?eid=bGx1dXBuc2x1a29mN3RzMmQzcGFjaWM4anMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", @@ -98,24 +84,29 @@ "date": "2023-11-28T16:00:00.000Z" }, { - "title": "Overview of AsyncAPI v3", - "calLink": "https://www.google.com/calendar/event?eid=ZWFpYjBwYzhoODRqMHA2bWRlcnIyZ241c3MgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/968", - "banner": "https://private-user-images.githubusercontent.com/40604284/285945520-e06ff77c-0e37-432e-964d-b4d47167cc18.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDExMDM4MzQsIm5iZiI6MTcwMTEwMzUzNCwicGF0aCI6Ii80MDYwNDI4NC8yODU5NDU1MjAtZTA2ZmY3N2MtMGUzNy00MzJlLTk2NGQtYjRkNDcxNjdjYzE4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzExMjclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMTI3VDE2NDUzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTgxMGM4ZGY0NWJmMTI3ZjA2NzcxNzc0YjQxYTBmMDNiY2NhZmQ5NDBlZTA0NzZkNzQ5NTgwNGRiZGRmNGQ0NjcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.PWfbBWAz2eGVDAGi8L1eFipmbAokRypMu9QDJBuv-Gk", - "date": "2023-12-14T13:00:00.000Z" + "title": "Community Meeting", + "calLink": "https://www.google.com/calendar/event?eid=M2I4MXRidmpqb2ZyZTUyajhsZm41ZjN0bTggY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/979", + "banner": "https://user-images.githubusercontent.com/40604284/288050762-4d064212-22ea-4af0-9d1a-b23c8fd70d6b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDE3ODI2MDUsIm5iZiI6MTcwMTc4MjMwNSwicGF0aCI6Ii80MDYwNDI4NC8yODgwNTA3NjItNGQwNjQyMTItMjJlYS00YWYwLTlkMWEtYjIzYzhmZDcwZDZiLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMDUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjA1VDEzMTgyNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWYzOGFhZmI5NzAxODljZDQ4NTFhNDc0NGIxNGQzZDZlZmU3ZjhhYTExOGU1YTRkN2FjODU1MzgzZGU0M2UzNmMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.-FT5AFf2Np1cFxMyXVga0zAfLjFc9fspwL-BJ_t7KLg", + "date": "2023-12-12T08:00:00.000Z" }, { - "title": "4 Request/Reply Use Cases", - "calLink": "https://www.google.com/calendar/event?eid=OXQ4MGVycWdsZ2g4ZmFibXZ1NHM2Y285NnMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/975", - "banner": "", - "date": "2023-12-14T18:00:00.000Z" + "title": "Overview of AyncAPI v3", + "calLink": "https://www.google.com/calendar/event?eid=c3E0Ym1qMTFnMDY5ODljdGk1ajh2anRrdjAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/981", + "banner": "https://user-images.githubusercontent.com/40604284/285945520-e06ff77c-0e37-432e-964d-b4d47167cc18.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDE3ODI1NzUsIm5iZiI6MTcwMTc4MjI3NSwicGF0aCI6Ii80MDYwNDI4NC8yODU5NDU1MjAtZTA2ZmY3N2MtMGUzNy00MzJlLTk2NGQtYjRkNDcxNjdjYzE4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMDUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjA1VDEzMTc1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWY5MjBhNTEwMjIwNDQxNzczY2EyMDI1YjQzOWIwYzRhY2MxNTU3ZDYyMGY2NzMxYjVkYzYyNmViZTM5Yjg4ZTEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.Dm-WJy2AQO2xUMAJ1nO6ADZuBFYXKj0NEFgdcDd44Fg", + "date": "2023-12-19T13:00:00.000Z" }, { - "title": "Building a Messaging System for E-commerce Orders", - "calLink": "https://www.google.com/calendar/event?eid=M2hpdmRkaW84ZmhybmlmbGg3cWw3c2tnNjAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/978", - "banner": "https://user-images.githubusercontent.com/40604284/287390698-ff955971-096e-4705-8ee9-2501ac632be8.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDE2MDE0OTIsIm5iZiI6MTcwMTYwMTE5MiwicGF0aCI6Ii80MDYwNDI4NC8yODczOTA2OTgtZmY5NTU5NzEtMDk2ZS00NzA1LThlZTktMjUwMWFjNjMyYmU4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMDMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjAzVDEwNTk1MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTdiMGVjMmU2YmU1NjQxM2M3ZmRkZmE3NTkyMTEwNDVmNjZlZjUyYjk1ZjRhYTljNWM3MDEyMmE2NTEwMWEzNzgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.zLrtMPxQvtThush9plXgKz3v7INAHk2bgOjsWRRwbJI", - "date": "2023-12-21T13:00:00.000Z" + "title": "AsyncAPI v3 announcement", + "calLink": "https://www.google.com/calendar/event?eid=NmhzMGZnNTRnZHNnZTFtbnRjbmhpZnJzbjAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "date": "2023-12-06T15:00:00.000Z" + }, + { + "title": "3 Request/Reply Use Cases", + "calLink": "https://www.google.com/calendar/event?eid=b3NvM2c0dW9tcTk1djRiMDJmbWU4dG9odGcgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/985", + "banner": "https://user-images.githubusercontent.com/40604284/288488243-e274e624-c5b3-4bff-b0ec-8c1929a24aae.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDE4ODI2MTUsIm5iZiI6MTcwMTg4MjMxNSwicGF0aCI6Ii80MDYwNDI4NC8yODg0ODgyNDMtZTI3NGU2MjQtYzViMy00YmZmLWIwZWMtOGMxOTI5YTI0YWFlLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjA2VDE3MDUxNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWUyMGYyNDE3Nzg4OGUyZGVmYjNlMDkxYzVkOWFkNjEwYjM4ZDI2YzZjZmUyYjRjMDliMDQ3YWJiNTVlNDI1MmQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.jYmY72ZRresQv1lMFeKwA49Wi6VkAozRpIHH4uE0J8g", + "date": "2023-12-14T18:00:00.000Z" } ] \ No newline at end of file diff --git a/config/newsroom_videos.json b/config/newsroom_videos.json index 79fb4f9e5d9..352d13b5def 100644 --- a/config/newsroom_videos.json +++ b/config/newsroom_videos.json @@ -1,4 +1,10 @@ [ + { + "image_url": "https://i.ytimg.com/vi/YREb9wuYCOA/hqdefault.jpg", + "title": "AsyncAPI v3 announcement", + "description": "Join us live to learn about all the goodies that AsyncAPI v3 brings.", + "videoId": "YREb9wuYCOA" + }, { "image_url": "https://i.ytimg.com/vi/g6CPg77Lf5Q/hqdefault.jpg", "title": "AsyncAPI Conf on Tour 2023 in Bangalore, India", @@ -22,11 +28,5 @@ "title": "Community Meeting(October 31th, 2023)", "description": "Powered by Restream https://restream.io https://github.com/asyncapi/community/issues/916.", "videoId": "Vm4ZKFb2PVE" - }, - { - "image_url": "https://i.ytimg.com/vi/FN5eR1Zqh9c/hqdefault.jpg", - "title": "AsyncAPI Conf on Tour 2023 in Madrid", - "description": "AACoT'23 Madrid Edition streamed live from StageOne at SNGULAR. 00:00 Waiting 57:12 Opening 1:26:07 Everything You Wish ...", - "videoId": "FN5eR1Zqh9c" } ] \ No newline at end of file diff --git a/cypress/test/components/campaignTests/AnnouncementHero.cy.js b/cypress/test/components/campaignTests/AnnouncementHero.cy.js index 3d5444d9b20..a2dc55b29bc 100644 --- a/cypress/test/components/campaignTests/AnnouncementHero.cy.js +++ b/cypress/test/components/campaignTests/AnnouncementHero.cy.js @@ -7,26 +7,28 @@ beforeEach(() => { mount(); }); +// .skip should be removed once the AnnouncementHero component is rendered in the website describe('AnnouncementHero Component', () => { - it('should render the component when the date is within the valid range', () => { + it.skip('should render the component when the date is within the valid range', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); cy.get('[data-testid="AnnouncementHero-main-div"]').should('exist'); }); //check if announcement rendered is small or large . - it('should render a small announcement when "small" prop is true', () => { + it.skip('should render a small announcement when "small" prop is true', () => { mount(); cy.get('[data-testid="AnnouncementHero-main-div"]').should('have.class', 'mb-4'); }); - it('should display the correct event information', () => { + it.skip('should display the correct event information', () => { // Assert the event details cy.get('[data-testid="Paragraph-test"]').should('exist'); cy.get('h2').should('exist'); }); - it('should have a link and text for the button', () => { + + it.skip('should have a link and text for the button', () => { mount(); cy.get('[data-testid="Button-link"]') .should('have.attr', 'target', '_blank') @@ -38,7 +40,7 @@ describe('AnnouncementHero Component', () => { }); //check if announcement rendered is small or large . - it('should render a small announcement when "small" prop is true', () => { + it.skip('should render a small announcement when "small" prop is true', () => { const mockDate = new Date('2023-05-01T00:00:00Z'); cy.clock(mockDate.getTime()); @@ -47,7 +49,7 @@ describe('AnnouncementHero Component', () => { cy.get('[data-testid="AnnouncementHero-main-div"]').should('have.class', 'mb-4'); }); - it('should render a large announcement when "small" prop is false', () => { + it.skip('should render a large announcement when "small" prop is false', () => { const mockDate = new Date('2023-05-01T00:00:00Z'); cy.clock(mockDate.getTime()); diff --git a/cypress/test/components/campaignTests/Banner.cy.js b/cypress/test/components/campaignTests/Banner.cy.js index 5ec6e4a1b47..fb196376002 100644 --- a/cypress/test/components/campaignTests/Banner.cy.js +++ b/cypress/test/components/campaignTests/Banner.cy.js @@ -2,8 +2,9 @@ import React from 'react'; import { mount } from '@cypress/react'; import Banner from '../../../../components/campaigns/Banner'; +// .skip should be removed once the Banner component is rendered in the website with default functionalities describe('Banner Component', () => { - it('should not render the banner when the date is not within the valid range', () => { + it.skip('should not render the banner when the date is not within the valid range', () => { const today = new Date(); const [day, month, year] = [today.getUTCDate(), today.getUTCMonth(), today.getUTCFullYear()]; if (year > 2022 || month !== 10 || day < 6) { @@ -17,21 +18,21 @@ describe('Banner Component', () => { } }); - it('should render the banner when the date is within the valid range', () => { + it.skip('should render the banner when the date is within the valid range', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); mount(); cy.get('[data-testid="Banner-main-div"]').should('be.visible'); }); - it('should display the correct message when the date is within the valid range', () => { + it.skip('should display the correct message when the date is within the valid range', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); mount(); cy.contains('.font-medium', 'AsyncAPI Conference 2022 has ended').should('be.visible'); }); - it('should have a link to the recordings playlist', () => { + it.skip('should have a link to the recordings playlist', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); mount(); @@ -41,7 +42,7 @@ describe('Banner Component', () => { .should('have.attr', 'rel', 'noopener noreferrer'); }); - it('should have the max-w-screen-xl class in the div element', () => { + it.skip('should have the max-w-screen-xl class in the div element', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); mount(); diff --git a/pages/about/index.md b/pages/about/index.md index 4714e54ac94..585dfa7b70a 100644 --- a/pages/about/index.md +++ b/pages/about/index.md @@ -100,11 +100,47 @@ All the information about the project's economy, the amount of the donations, th ## FAQs -- **What is the goal of the project?** To make asynchronous APIs as successful and mature as REST APIs. -- **What protocols does it support?** AsyncAPI is protocol-agnostic, so you can use it for APIs that work over any protocol (e.g., AMQP, MQTT, WebSockets, Kafka, STOMP, HTTP, Mercure, etc). For more information, refer to the [AsyncAPI specification documentation](https://www.asyncapi.com/docs/reference/specification/latest#serverBindingsObject). -- **Who are the users of AsyncAPI?** AsyncAPI users are those who implement and maintain event-driven architecture. For example, people that write backend API using WebSocket, or people that maintain communication between their microservices using Kafka. -- **What is the AsyncAPI Community?** It’s the core of the initiative. The AsyncAPI community contributes to the development of the tool, it promotes access and distribution of the specification allowing freedom of use, study, copying, modification, and redistribution to anyone who wishes to do so. The cooperation between these people in all areas of software production generates a substantial improvement in the quality of the software, as well as greater dissemination and sustainability over time, and prioritizing the benefit of society over any other. -- **Who can use it?** Anyone. All projects under AsyncAPI Initiative are part of the Linux Foundation, licensed under the Apache 2.0 license. It’s open to use and contribution. -- **Where can I find more information?** - - [Official AsyncAPI Documentation](/docs) - - [Presentation by Fran Méndez, explaining the project](https://www.youtube.com/watch?v=UID1nnuFDtM&list=PLbi1gRlP7piitNgvqhIAvGNZM_kvP0r8R) +
+What is the goal of the project? + +

To make asynchronous APIs as successful and mature as REST APIs.

+ +
+ +
+What protocols does it support? + +

AsyncAPI is protocol-agnostic, so you can use it for APIs that work over any protocol (e.g., AMQP, MQTT, WebSockets, Kafka, STOMP, HTTP, Mercure, etc). For more information, refer to the [AsyncAPI specification documentation](https://www.asyncapi.com/docs/reference/specification/latest#serverBindingsObject). +

+ +
+ +
+Who are the users of AsyncAPI? + +

AsyncAPI users are those who implement and maintain event-driven architecture. For example, people that write backend API using WebSocket, or people that maintain communication between their microservices using Kafka.

+ +
+ +
+What is the AsyncAPI Community? + +

It’s the core of the initiative. The AsyncAPI community contributes to the development of the tool, it promotes access and distribution of the specification allowing freedom of use, study, copying, modification, and redistribution to anyone who wishes to do so. The cooperation between these people in all areas of software production generates a substantial improvement in the quality of the software, as well as greater dissemination and sustainability over time, and prioritizing the benefit of society over any other.

+ +
+ +
+Who can use it? + +

Anyone. All projects under AsyncAPI Initiative are part of the Linux Foundation, licensed under the Apache 2.0 license. It’s open to use and contribution.

+ +
+ +
+Where can I find more information? + + [Official AsyncAPI Documentation](/docs) + + [Presentation by Fran Méndez, explaining the project](https://www.youtube.com/watch?v=UID1nnuFDtM&list=PLbi1gRlP7piitNgvqhIAvGNZM_kvP0r8R) + +
diff --git a/pages/docs/migration/migrating-to-v3.md b/pages/docs/migration/migrating-to-v3.md index 95b6709ca9a..73f48d79494 100644 --- a/pages/docs/migration/migrating-to-v3.md +++ b/pages/docs/migration/migrating-to-v3.md @@ -19,7 +19,7 @@ Asyncapi3ParameterComparison} from '../../../components/Asyncapi3Comparison' ## Moved metadata -In v2, two properties of `tags` and `externalDocs` were placed outside of the [Info Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.12#infoObject). For consistency, `info` has been moved in v3. +In v2, two properties of `tags` and `externalDocs` were placed outside of the [Info Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#infoObject). For consistency, `info` has been moved in v3. @@ -45,7 +45,7 @@ info: ``` ## Server URL splitting up -There was occasional confusion regarding what the URL of a [Server Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.12#serverObject) should include. +There was occasional confusion regarding what the URL of a [Server Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#serverObject) should include. @@ -124,7 +124,7 @@ Read more about the confusion between publishing and subscribing in the [Operati ## Channel address and channel key -Another breaking change is that the channel key no longer represents the channel path. Instead, it's now an arbitrary unique ID. The channel paths are now defined using the `address` property within the [Channel Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.12#channelObject). +Another breaking change is that the channel key no longer represents the channel path. Instead, it's now an arbitrary unique ID. The channel paths are now defined using the `address` property within the [Channel Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#channelObject). @@ -149,7 +149,7 @@ channels: ## Operation keywords -Another significant change is the shift away from defining operations using `publish` and `subscribe`, which had inverse meanings for your application. Now, you directly specify your application's behavior using `send` and `receive` via the `action` property in the [Operation Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.12#operationObject). +Another significant change is the shift away from defining operations using `publish` and `subscribe`, which had inverse meanings for your application. Now, you directly specify your application's behavior using `send` and `receive` via the `action` property in the [Operation Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#operationObject). @@ -196,7 +196,7 @@ operations: ## Messages instead of message In v2, channels were defined with one or more messages using the `oneOf` property. -In v3, messages are defined using the [Messages Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.12#messagesObject). For a channel with multiple messages, you specify multiple key-value pairs. For a channel with just one message, you use a single key-value pair. +In v3, messages are defined using the [Messages Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#messagesObject). For a channel with multiple messages, you specify multiple key-value pairs. For a channel with just one message, you use a single key-value pair. ```yml asyncapi: 2.6.0 @@ -247,7 +247,7 @@ We have updated the structure of the Message Object by eliminating the `messageI In v2, implicit references were allowed in certain instances. For instance, the server security configuration was identified by name, linking to a [Security Schema Object](https://www.asyncapi.com/docs/reference/specification/v2.6.0#securitySchemeObject) within the components. Similarly, a channel could reference global servers by name. -In v3, all such references MUST be explicit. As a result, we made a minor modification to the [Server Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.12#serverObject) `security` property, transforming it from an object to an array. The details regarding required scopes for OAuth and OpenID Connect were then relocated to the [Security Scheme Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.12#securitySchemeObject). +In v3, all such references MUST be explicit. As a result, we made a minor modification to the [Server Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#serverObject) `security` property, transforming it from an object to an array. The details regarding required scopes for OAuth and OpenID Connect were then relocated to the [Security Scheme Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#securitySchemeObject). ```yml asyncapi: 2.6.0 @@ -259,7 +259,7 @@ servers: ... channels: test/path: - severs: + servers: - production components: securitySchemes: @@ -285,7 +285,7 @@ servers: ... channels: test/path: - severs: + servers: - $ref: "#/servers/production" components: securitySchemes: @@ -347,7 +347,7 @@ One limitation with schemas has always been the inability to reuse them across d In v2, the details about which schema format the payload uses are found within the message object, rather than being directly linked to the schema itself. Such separation hampers reusability, as the two data points aren't directly correlated. -To address this in v3, we've introduced [a multi-format schema object](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.12#multiFormatSchemaObject) that consolidates this information. Consequently, whenever you utilize `schemaFormat`, you'll need to modify the schema as follows: +To address this in v3, we've introduced [a multi-format schema object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#multiFormatSchemaObject) that consolidates this information. Consequently, whenever you utilize `schemaFormat`, you'll need to modify the schema as follows: ```yml asyncapi: 2.6.0 diff --git a/pages/docs/tools/glee/_section.md b/pages/docs/tools/glee/_section.md new file mode 100644 index 00000000000..12696528246 --- /dev/null +++ b/pages/docs/tools/glee/_section.md @@ -0,0 +1,4 @@ +--- +title: Glee +weight: 10 +--- \ No newline at end of file diff --git a/pages/docs/tools/glee/authentication.md b/pages/docs/tools/glee/authentication.md new file mode 100644 index 00000000000..2cd7a0101c7 --- /dev/null +++ b/pages/docs/tools/glee/authentication.md @@ -0,0 +1,188 @@ +--- +title: 'Authentication functions' +weight: 3 +--- + +# Getting started with Authentication functions + +Authentication in Glee can be done using authentication functions. Authentication functions are files that export either one or both of the `clientAuth` and `serverAuth` Node.js functions: + +```js +/* websocket.js */ + +export async function serverAuth({ authProps, done }) { + //server auth logic +} + +export async function clientAuth({ parsedAsyncAPI, serverName }) { + //client auth logic +} +``` + +Glee looks for authentication files in the `auth` directory by default but it can be configured using [glee config file](../config-file.md). +The name of the authentication file should be the name of the targeted server that the authentication logic should work for. + +## Supported Authentication Values in asyncapi.yaml file + +AsyncAPI currently supports a variety of authentication formats as specified in the [documentation](https://www.asyncapi.com/docs/reference/specification/v3.0.0-next-major-spec.15#securitySchemeObject), however Glee supports the following authentication schemas. + +- userPassword +- http ("bearer") +- httpApiKey +- Oauth2 + +A sample `asyncapi.yaml` for a server with security requirements and a `userPassword` security schemes is shown below: + +```yaml +##server asyncAPI schema +asyncapi: 3.0.0 +info: + title: AsyncAPI IMDB server + version: 1.0.0 + description: This app is a dummy server that would stream the trending/upcoming anime. +servers: + trendingAnimeServer: + host: 'localhost:8081' + protocol: http + security: + - $ref: '#/components/securitySchemes/userPass' + + ... + +components: + securitySchemes: + userPass: + type: userPassword + +``` + +A sample `asyncapi.yaml` for a client that implements some of the requirements of the server above: + +```yaml +##client asyncAPI schema +servers: + trendingAnime: + host: localhost:8081 + protocol: http + security: + - $ref: '#/components/securitySchemes/userPass' + testwebhook: + host: localhost:9000 + protocol: ws +x-remoteServers: + - trendingAnime + + ... + +components: + securitySchemes: + userPass: + type: userPassword + +``` + +**The Client asyncapi.yaml file does not need to implement all the security requirements in the server, it only needs to implement the ones that it uses like *userPassword* here.** + + +Glee can act as both a server and a client. Hence the need for `serverAuth` and `clientAuth`. Glee acts as a client when the server name is included in the `x-remoteServers` property in the `asyncapi.yaml` file. + +When Glee acts as a client, it can connect to a Glee server, and when Glee acts as a server it accepts connections from other Glee clients. Hence a Glee application can both accept connections from clients while also sending requests to other Glee applications (servers) at the same time. + +When a security requirement is specified in the `asyncapi.yaml` file and Glee acts as a server, the `serverAuth` function should be implemented, if Glee acts as a client then the `clientAuth` function should be implemented. If Glee is being used as both client and server, then it should have both the `clientAuth` and `serverAuth` functions. + +## Server Authentication in Glee + +The `serverAuth` function takes an argument that can be destructured as follows + +| Attribute | Description | +| ---------- | --------------------------------------------------------------- | +| done | The done function that tells the server to proceed. | +| authProps | The authentication parameters recieved from the client. | +| serverName | The name of the server/broker from which the event was emitted. | +| doc | The parsedAsyncAPI schema | + +### done() + +The `done` parameter in the `serverAuth` function allows the broker/server to know what to do next depending on the boolean value you pass to it. + +```js +/* websocket.js */ + +export async function serverAuth({ authProps, done }) { + if (isValidUser(authProps)) { + done(true); + } else { + done(false, 401, "Unauthorized"); + } +} +``` +**Parameters for done():** + +- Authentication Result (Boolean): true for success, false for failure. +- HTTP Status Code (Integer): Code for authentication failure (e.g., 401 for Unauthorized). +- Status Message (String): Description of the authentication result (e.g., "Unauthorized"). + +When `true` is passed to the done parameter, the server/broker knows to go ahead and allow the client to connect, which means authentication has succeeded. However if the `done` parameter is called with `false` then the server knows to throw an error message and reject the client, which means authenticatio has failed. + +`done()` should always be the last thing called in a `serverAuth` function, Glee won't execute any logic beyond the `done()` call. + +### authProps + +`authProps` implements a couple of methods that allows the server to retrieve the authentication parameters from the client, below are the current available methods; + +```js +export async function serverAuth({ authProps, done }) { + //some network request + + authProps.getOauthToken() + authProps.getHttpAPIKeys('api_key') + authProps.getToken() + authProps.getUserPass() + + // done(false, 401, "Unauthorized"); + done(false) +} +``` + +| Method | Description | +| ---------------------- | ------------------------------------------------------------------------------------------------ | +| `getOauthToken()` | returns the oauth authentication parameter | +| `getHttpAPIKeys(name)` | returns the HttpAPIKeys parameter with the specified name from either headers or query parameter | +| `getToken()` | returns the http bearer token parameter | +| `getUserPass()` | returns username and password parameters | + +## Client Authentication in Glee + +The `clientAuth` function also takes an argument, and it's argument can be destructured as follows + +| Attribute | Description | +| -------------- | ------------------------------------------------------------------------------------- | +| parsedAsyncAPI | The parsedAsyncAPI schema. | +| serverName | The name of the server/broker from with the authentication parameters are being sent. | + +### possible authentication parameters + +The possible authentication parameters are shown in the code snippet below: + +```js +export async function clientAuth({ serverName }) { + return { + token: process.env.TOKEN, + oauth: process.env.OAUTH2, + apiKey: process.env.APIKEY, + userPass: { + user: process.env.user, + password: process.env.password, + }, + } +} +``` + +**The name of the authentication parameters should be the same as the names specified in the asyncAPI.yaml file.** + +| auth type | values | +| ------------------------------------- | ---------------------------------------------------------------------- | +| http bearer (JWT) | Value should be a JWT string | +| Oauth2 | The value should should be a string | +| httpApiKey in headers or query params | The value should be a string | +| userPass | The value should be an object with the user and password as properties | diff --git a/pages/docs/tools/glee/bearerToken.md b/pages/docs/tools/glee/bearerToken.md new file mode 100644 index 00000000000..9f1d2244ba2 --- /dev/null +++ b/pages/docs/tools/glee/bearerToken.md @@ -0,0 +1,109 @@ +--- +title: 'Http (Bearer Token)' +weight: 5 +--- + +## Getting started with Bearer Token authentication + +Bearer Token authentication is one of the most popular forms of authentication and is widely used because of its percieved security. This guide will walk through how to implement bearer token authentication in Glee. + +A sample `asyncapi.yaml` for a server with security requirements and user password security scheme is shown below: + +```yaml +##server asyncAPI schema +asyncapi: 3.0.0 +info: + title: AsyncAPI IMDB server + version: 1.0.0 + description: This app is a dummy server that would stream the trending/upcoming anime. +servers: + trendingAnimeServer: + host: 'localhost:8081' + protocol: http + security: + - $ref: '#/components/securitySchemes/token' + + ... + +components: + securitySchemes: + token: + type: http + scheme: bearer + bearerFormat: JWT + +``` + +A sample `asyncapi.yaml` for a client that implements some of the requirements of the server above: + +```yaml +##client asyncAPI schema +servers: + trendingAnime: + host: localhost:8081 + protocol: http + security: + - $ref: '#/components/securitySchemes/token' + testwebhook: + host: localhost:9000 + protocol: ws +x-remoteServers: + - trendingAnime + + ... + +components: + securitySchemes: + token: + type: http + scheme: bearer + bearerFormat: JWT + +``` + +**The Client asyncapi.yaml file does't need to implement all the security requirements in the server, it only needs to implement the ones that it uses like &*http (bearer token)* here.** + +### Client Side + +Following the client `asyncapi.yaml` file above, create a file named `trendingAnime.ts` in the `auth` directory, since that is the server that has the security Property. + +```bash +touch auth/trendingAnime.ts +``` + +When using the `bearer` security scheme, it is important that you pass the parameters as follows: + +```js +export async clientAuth({ parsedAsyncAPI, serverName }) { + return { + token: process.env.TOKEN + } +} +``` + +Glee will utilize the `token` for server authentication, employing it in the header with the format: Authorization: Bearer {token}. + +### Server side + +From the server `asyncapi.yaml` file above, create a file named `trendingAnimeServer.ts` in the `auth` directory, since that is the server that has the security Property. + +```bash +touch auth/trendingAnimeServer.ts +``` + +On the server side, you can retrieve the values as follows + +```js + +export async serverAuth({ authProps, done }) { + authProps.getToken() + // your authentication logic here... + done(true|false) +} + +``` + +`getToken()` return a string which contains the token that was sent from the client. + + + diff --git a/pages/docs/tools/glee/glee-template.md b/pages/docs/tools/glee/glee-template.md new file mode 100644 index 00000000000..346a28bacb3 --- /dev/null +++ b/pages/docs/tools/glee/glee-template.md @@ -0,0 +1,104 @@ +--- +title: "Create AsyncAPI Glee template" +weight: 170 +--- +This tutorial teaches you how to create a simple glee template. You'll use the AsyncAPI Glee template you develop to generate Javascript code. Additionally, you'll create a template code with a reusable component to reuse the custom functionality you create and test your code using an WS server. + + +{`asyncapi: 3.0.0 +info: + title: 'Hello, Glee!' + version: 1.0.0 +servers: + websockets: + host: 0.0.0.0:3000 + protocol: ws +channels: + hello: + address: hello + messages: + hello: + $ref: '#/components/messages/hello' +operations: + onHello: + action: receive + channel: + $ref: '#/channels/hello' + reply: + channel: + $ref: "#/channels/hello" + SendHello: + action: send + channel: + $ref: "#/channels/hello" +components: + messages: + hello: + payload: + type: string`} + + +Let's break it down into pieces: + + +{`info: + title: 'Hello, Glee!' + version: 1.0.0`} + + +The `info` section provides general information about the API, including its title and version. + +Moving on, let's talk about the `servers` section. + + +{`servers: + websockets: + host: 0.0.0.0:3000 + protocol: ws`} + + +The servers section defines the different servers where the API can be accessed. In this case, there is a single server named "websockets" that uses the WebSocket protocol (`ws`) and listens on the address `ws://0.0.0.0:3000`. + +Now lets move on to the `channels` section. This section is used to describe the event names your API will be publishing and/or subscribing to. + + +{`channels: + hello: + address: hello + messages: + hello: + $ref: '#/components/messages/hello' +operations: + onHello: + action: receive + channel: + $ref: '#/channels/hello' + reply: + channel: + $ref: "#/channels/hello" + sendHello: + action: send + channel: + $ref: '#/channels/hello'`} + + +The channels section defines the communication channels available in the API. In this case, there's a channel named "hello". This channel supports both sending and receiving. + +The `receive` action indicates that messages received on the `hello` channel should follow the structure defined in the hello message component. Under this action, `reply` which is in a request-reply operation, contains the payload on `onHello.js` function. +The `send` action specifies that the operation with ID `sendHello` is used for sending messages to the `hello` channel. The message structure is referenced from the hello message component. + +Next is the `payload` property under `hello` message component which is used to understand how the event should look like when publishing to that channel: + + +{`components: + messages: + hello: + payload: + type: string`} + + +The components section contains reusable elements, in this case, a definition for the "hello" message. It specifies that the payload of the "hello" message should be of type string. + +## Summary + +In this tutorial, you learned how to create an AsyncAPI specification document via a simple example with a glee template. diff --git a/pages/docs/tools/glee/httpApiKey.md b/pages/docs/tools/glee/httpApiKey.md new file mode 100644 index 00000000000..e95131edbaa --- /dev/null +++ b/pages/docs/tools/glee/httpApiKey.md @@ -0,0 +1,111 @@ +--- +title: 'httpAPIKey' +weight: 5 +--- + +## Getting started with httpAPIKey authentication + +This guide will walk through how to implement authentication using the `httpAPiKey` security scheme in Glee. + +A sample `asyncapi.yaml` for a server with security requirements and user `HttpApiKey` security scheme is shown below: + +```yaml +##server asyncAPI schema +asyncapi: 3.0.0 +info: + title: AsyncAPI IMDB server + version: 1.0.0 + description: This app is a dummy server that would stream the trending/upcoming anime. +servers: + trendingAnimeServer: + host: 'localhost:8081' + protocol: http + security: + - $ref: '#/components/securitySchemes/apiKey' + + ... + +components: + securitySchemes: + apiKey: + type: httpApiKey + name: api_key + in: query + +``` + +A sample `asyncapi.yaml` for a client that implements some of the requirements of the server above: + +```yaml +##client asyncAPI schema +servers: + trendingAnime: + host: localhost:8081 + protocol: http + security: + - $ref: '#/components/securitySchemes/apiKey' + testwebhook: + host: localhost:9000 + protocol: ws +x-remoteServers: + - trendingAnime + + ... + +components: + securitySchemes: + apiKey: + type: httpApiKey + name: api_key + in: query + + +``` + +The `httpApiKey` could be in either the header or query parameter. + +**The Client asyncapi.yaml file does not need to implement all the security requirements in the server, it only needs to implement the ones that it uses like *httpApiKey* here.** + +### Client Side + +Following the client `asyncapi.yaml` file above, create a file named `trendingAnime.ts` in the `auth` directory, since that is the server that has the security Property. + +```bash +touch auth/trendingAnime.ts +``` + +When using the `HttpApiKey` security scheme, it is important that you pass the parameters as follows: + +```js +export async clientAuth({ parsedAsyncAPI, serverName }) { + return { + apiKey: process.env.APIKEY + } +} +``` + +`apiKey` should be the name of the security requirement as specified in your `asyncapi.yaml` file, and it's value should be a string. + + +### Server side + +From the server `asyncapi.yaml` file above, create a file named `trendingAnimeServer.ts` in the `auth` directory, since that is the server that has the security Property. + +```bash +touch auth/trendingAnimeServer.ts +``` + +On the server side, you can retrieve the values as follows + +```js + +export async serverAuth({ authProps, done }) { + authProps.getHttpAPIKeys('api_key')() + + done(true) +} + +``` + +`getHttpAPIKeys(name)` takes a name parameter to specify the name of the httpApiKey that is desired. Then it returns an object containing the httpApiKey value that was sent from the client. + diff --git a/pages/docs/tools/glee/index.md b/pages/docs/tools/glee/index.md new file mode 100644 index 00000000000..aca98544169 --- /dev/null +++ b/pages/docs/tools/glee/index.md @@ -0,0 +1,159 @@ +--- +title: Getting Started +weight: 80 +--- + +## Introduction + +[Glee](https://github.com/asyncapi/glee) is a spec-first framework that helps you build server-side applications. That means it operates on the principle of defining the API specification (AsyncAPI) before diving into the actual implementation of the application logic. It leverages that principle to make you more productive: + +- Glee ensures your code and AsyncAPI definition are on par, eliminating the problem of outdated documentation. By having both the code and the AsyncAPI definition in sync, you can ensure that the API documentation is always up to date, accurate, and reflects the current state of the application. Glee takes care of this automatically for you. +- Glee lets you focus on what matters and handles the rest for you. You only write the code for your business use-case. Glee takes care of performance, scalability, resilience, and everything you need to make your application production-ready. +- Glee validates the schema of the payload that it receives, if it doesn't conform to the schema that is defined in the AsyncAPI document, it throw an error telling user that the server received an invalid payload. + +Now, before you get started with a glee project, let's take a high level view of Application structure what glee resonates with. + +## Application structure + +Glee expects your project to have some files and folders with special names. When you run `asyncapi new glee`, [AsyncAPI CLI](https://github.com/asyncapi/cli) generates a boilerplate application structure by creating a new folder and populating an initial set of files as shown below. You can continue working in this default structure, adding new components, as described throughout the documentation of asyncapi cli. + +``` +├─ functions (required) +│ ├─ onHello.js +│ └─ ... +├─ lifecycle (optional) +│ ├─ onConnect.js +│ └─ ... +├─ .env (optional) +├─ asyncapi.(yaml | yml | json) (required) +├─ glee.config.js (optional) +├─ package.json (required) +``` + +|File/Directory|Description| +|---|---| +|functions|**Required.** This directory contains all the functions that Glee must execute when it receives a message from the server. Each file must export a default async function. +|lifecycle|This directory contains application lifecycle functions. These functions will be executed when certain events happen in the application. E.g., `onConnect`, `onServerReady`, `onDisconnect`, etc. +|.env|The environment variables of your application. **DO NOT PUT SECRETS HERE**. +|asyncapi.(yaml or json or yml)|**Required.** The [AsyncAPI](https://www.asyncapi.com/docs/specifications/latest) file defines your API. Make sure all the `publish` operations have an assigned `operationId` that matches a file name (excluding the extension) in the `functions` directory. +|glee.config.js| The Glee configuration file. +|package.json|**Required.** The Node.js package definition file. Make sure you include `@asyncapi/glee` as a dependency and add two scripts: `dev` and `start`. They should be running `glee dev` and `glee start` respectively. + +To understand the structure in a broader way, please refer to the associated page's links. + +### Let's create a glee project to simplify the app structure + +We will consider a simple WebSocket API using glee to understand its magic. We will create a simple WebSocket server that receives a current time from the client and then send a "good morning", "good evening" or "good night" respectively. + +To setup a project, you should follow our installation page on how to setup glee on your environment. + +We recommend creating a new Glee app using our official CLI which sets up everything automatically. (You don't need to create an empty directory. create-glee-app will make one for you.) To create a project, run: `asyncapi new glee` + +Once the process is completed, you should have a new Glee app ready for development and see these files that were made. + +![glee_structure](glee_struct.png) + +#### Define our Spec for our API + +Glee being a spec-first framework, development starts with defining your API spec. To know more details into it, you can follow glee template to understand it step by step. For our case we will define our API: + +```yaml +asyncapi: 3.0.0 +info: + title: Greet Bot + version: 1.0.0 +servers: + websockets: + host: 0.0.0.0:3000 + protocol: ws +channels: + greet: + address: greet + messages: + greet: + $ref: '#/components/messages/greet' + time: + $ref: '#/components/messages/time' + time: + address: time + messages: + time: + $ref: '#/components/messages/time' +operations: + onGreet: + action: receive + channel: + $ref: '#/channels/greet' + reply: + channel: + $ref: '#/channels/greet' + sendGreet: + action: send + channel: + $ref: '#/channels/time' +components: + messages: + time: + payload: + type: object + properties: + currentTime: + type: number + name: + type: string + greet: + payload: + type: string + +``` + +This will be the Specification that defines our API, in our case, it is very simple, as we will be sending a name and the time of the day, and our API will greet us accordingly. + +One thing to note here is the `operations` item, this is needed and is a crucial part of glee, as this is how we will be connecting our business logic with our spec, `onGreet` is the name of the function that will be called every time a certain operation occurs. In our case whenever `/greet` channel receives a message, `onGreet` function is called. + +#### Define our operation function + +Now for our case, we will be adding a file `functions/onGreet.js` and writing up the logic for parsing our time and sending a response. + +```javascript +export default async function (event) { + const { name, time } = event.payload + const t = new Date(time) + const curHr = t.getHours() + let response = '' + if (curHr < 12) { + response = `Good Morning ${name}` + } else if (curHr < 18) { + response = `Good Afternoon ${name}` + } else { + response = `Good Evening ${name}` + } + return { + reply: [ + { + payload: response, + }, + ], + } +} + +``` + +Every file in the functions folder acts as a handler to develop business logic for glee, every file should export an async function that receives an event parameter, where you have access to payload and server details. + +#### Running and testing your application + +We will not execute the application and carry out testing with Postman to ensure that it is functioning as intended. + +Now to execute your glee application, just run: + +``` +npm run dev +# or +npm run start +``` +To send a WebSocket request with a payload e.g. `{"name":"john", "time": "1567906535"}` to `ws://localhost:3000/greet`, open Postman and checkout the endpoint: + +![glee_response](glee_resp.png) + +So, this is how easy it is to build a WebSocket API using Glee. You can also check out the example code [here](https://github.com/Souvikns/greet-bot). diff --git a/pages/docs/tools/glee/installation.md b/pages/docs/tools/glee/installation.md new file mode 100644 index 00000000000..3b13855e248 --- /dev/null +++ b/pages/docs/tools/glee/installation.md @@ -0,0 +1,134 @@ +--- +title: 'Installation guide' +weight: 30 +--- + +## Glee Installation + +Before installing Glee into your project, make sure you have pre-installed NPM, NodeJs and [AsyncAPI CLI](https://github.com/asyncapi/cli) tools on your system. + +### Automatic Installation + +The best way to get started with Glee is by using AsyncAPI CLI, which sets up everything automatically for you. +To create a project, run: + +```sh +asyncapi new glee +``` + +> For more information on how to install the AsynAPI CLI, you can review the [CLI installation guide](https://www.asyncapi.com/docs/tools/cli/installation). + +On installation, you'll find next steps after your project created: + +``` +Your project "project" has been created successfully! + +Next steps: + + cd project + npm install + npm run dev + +Also, you can already open the project in your favorite editor and start tweaking it +``` + +While making twists to your application, you can follow along with our getting started guide on the relevant page. + +### Manual Installation + +To manually create a new app, create a new folder e.g. `myapp` so the folder structure would look like below; + +``` +├─ functions (required) +│ ├─ onHello.js +│ └─ ... +├─ lifecycle (optional) +│ ├─ onConnect.js +│ └─ ... +├─ .env (optional) +├─ asyncapi.(yaml | yml | json) (required) +├─ glee.config.js (optional) +├─ package.json (required) +``` + +Install the required packages inside a new folder: + +```js +npm init -y +npm install @asyncapi/glee +``` + +Open your package.json file and add the following scripts: + +```js +{ + "scripts": { + "docs": "glee docs", + "dev": "glee dev", + "start": "glee start", + } +} +``` + +These scripts refer to the different stages of developing an application. + +- `glee docs`: This script generates documentation for your project using the "Glee" documentation tool. This documentation includes information about your project's APIs, modules, and usage instructions. + +- `glee dev`: This script is used for starting a development server. It launches a local development server, build your project in development mode, or perform other development-related tasks. + +- `glee start`: This script is responsible for starting your project or application. It is used to launch a production-ready server or application instance. + +#### Creating `asyncapi.yaml` file and other required directories + +Create a yaml file that supports capable of receiving a "hello {name}" message with the protocol as `ws` and the channel name as `hello` the hello API will subscribe to. The operationId property is `onHello` that's the name of function and the payload property is type string publishing to that channel. + +```yaml +asyncapi: 3.0.0 +info: + title: 'Hello, Glee!' + version: 1.0.0 +servers: + websockets: + host: 0.0.0.0:3000 + protocol: ws +channels: + hello: + address: hello + messages: + hello: + $ref: '#/components/messages/hello' +operations: + onHello: + action: receive + channel: + $ref: '#/channels/hello' + reply: + channel: + $ref: "#/channels/hello" + SendHello: + action: send + channel: + $ref: "#/channels/hello" +components: + messages: + hello: + payload: + type: string +``` + +Create an operation function `onHello.js` inside `myapp/functions`: + +```js +export default async function (event) { + return { + reply: [{ + payload: `Hello from Glee! You said: "${event.payload}".` + }] + } +} +``` + +#### Run the Development Server + +- Run `npm run dev` to start the development server. +- Connect to `ws://localhost:3000/hello` and send a WebSocket request with a payload e.g. {"john"} diff --git a/pages/docs/tools/glee/intro-auth.md b/pages/docs/tools/glee/intro-auth.md new file mode 100644 index 00000000000..c657fef8ecd --- /dev/null +++ b/pages/docs/tools/glee/intro-auth.md @@ -0,0 +1,21 @@ +--- +title: 'Introduction to Glee Authentication' +weight: 30 +--- + +Glee comes with Authentication features which help you erifying the identity of users or entities attempting to access a system or application. It ensures that only authorised individuals or systems are granted access, protecting against unauthorised intrusions and data breaches. Glee simplifies this vital process by offering multiple authentication methods, each tailored to different use cases: + +# Authentication Using Authentication Functions: +Glee allows you to implement custom authentication logic by utilising authentication functions. This flexible approach enables developers to craft tailored authentication mechanisms, ensuring that access to resources is controlled precisely as required. + + +# HTTP Bearer Token Authentication: +In today's API-driven world, bearer token authentication is a widely adopted method. Glee supports this approach, allowing clients to present a token as proof of their identity, thus ensuring secure and efficient access to resources. + +# HttpApiKey Authentication: +Glee's authentication suite includes support for API key authentication, which is vital for protecting web APIs. By using API keys, you can regulate access to your services, making it an essential component of your application's security strategy. + +# Username and Password Authentication: +Traditional yet still crucial, username and password authentication remains a reliable option within Glee's toolkit. This method allows users to access systems or applications by providing their unique credentials, ensuring a familiar and straightforward login experience. + +Glee's authentication features not only provide layers of security but also offer the flexibility needed to meet your unique requirements. Whether you're developing a web application, a mobile app, or any other application, Glee's authentication methods empower you to tailor your security measures to suit the demands of your project. With Glee, you can build and maintain a secure digital environment, ensuring that only authorised users and systems gain access, protecting your valuable data and resources. \ No newline at end of file diff --git a/pages/docs/tools/glee/userPassword.md b/pages/docs/tools/glee/userPassword.md new file mode 100644 index 00000000000..fc761310ed1 --- /dev/null +++ b/pages/docs/tools/glee/userPassword.md @@ -0,0 +1,106 @@ +--- +title: 'userPassword' +weight: 5 +--- + +## Getting started with username and password authentication + +User and password authentication is one of the most basic forms of authentication. This guide will walk through how to implement username and password authentication in Glee. + +A sample `asyncapi.yaml` for a server with security requirements and user password security scheme is shown below: + +```yaml +##server asyncAPI schema +asyncapi: 3.0.0 +info: + title: AsyncAPI IMDB server + version: 1.0.0 + description: This app is a dummy server that would stream the trending/upcoming anime. +servers: + trendingAnimeServer: + host: 'localhost:8081' + protocol: http + security: + - $ref: '#/components/securitySchemes/userPass + + ... + +components: + securitySchemes: + userPass: + type: userPassword + +``` + +A sample `asyncapi.yaml` for a client that implements some of the requirements of the server above: + +```yaml +##client asyncAPI schema +servers: + trendingAnime: + host: localhost:8081 + protocol: http + security: + - $ref: '#/components/securitySchemes/userPass + testwebhook: + host: localhost:9000 + protocol: ws +x-remoteServers: + - trendingAnime + + ... + +components: + securitySchemes: + userPass: + type: userPassword + +``` + +**The Client asyncapi.yaml file does not need to implement all the security requirements in the server, it only needs to implement the ones that it uses like &*userPassword* here.** + +### Client Side + +Following the client `asyncapi.yaml` file above, create a file named `trendingAnime.ts` in the `auth` directory, since that is the server that has the security Property. + +```bash +touch auth/trendingAnime.ts +``` + +When using the `userPassword` security scheme, it is important that you pass the parameters as follows: + +```js +export async clientAuth({ parsedAsyncAPI, serverName }) { + return { + userPass: { + user: process.env.user, + password: process.env.password, + }, + } +} +``` + +`userPass` should be the name of the security requirement as specified in your `asyncapi.yaml` file, then pass `user` and `password` as it's properties + + +### Server side + +From the server `asyncapi.yaml` file above, create a file named `trendingAnimeServer.ts` in the `auth` directory, since that is the server that has the security Property. + +```bash +touch auth/trendingAnimeServer.ts +``` + +On the server side, you can retrieve the values as follows + +```js + +export async serverAuth({ authProps, done }) { + authProps.getUserPass() + + done(true) +} + +``` + +`getUserPass()` return an object containing the username and password that was sent from the client.