# Form Builder API Reference ## SignalR Hub (Websocket) The Form builder SignalR Hub URL is ```txt {backend-url}/FormBuilderHub ``` Events (`Message Names for subscription`): - Session Events - `AllSessionsFormBuilderClosedEvent` - `UserJoinedFormBuilderEvent` - `UserLeftFormBuilderEvent` - Form Events - `ControlAddedEvent` - `ControlMovedEvent` - `ControlRemovedEvent` - `FormHistoryRevertedEvent` - `PropertyValueChangedEvent` Requests (`Methods to be invoked`): - Session Requests - `JoinFormBuilder` - `Authorize` - Form Requests - `AddControl` - `ChangePropertyValue` - `MoveControl` - `RemoveControl` - `RevertFormHistory` ### Authorize User This method should be called after connecting with the signalR Hub, It should also be called if the current token has been expired to send a new valid token. > Note: This method is a mock and accepts any string and create a random userid for the session. ```cs Result<bool> Authorize(string accessToken); ``` Response: ```json { "hasErrors": false, "data": false, "errors": [ { "code": "...", "description": "..." } ] } ``` Errors: | Code | # | Notes | | -------------------------- | --- | ------------- | | `InternalServerError` | | Unknown Error | ### Join for Specific Form This method should be called once the user is authorized before getting any data or sending any form related requests. ```cs Result<bool> JoinFormBuilder(Guid formId) ``` Response: ```json { "hasErrors": false, "data": false, "errors": [ { "code": "...", "description": "..." } ] } ``` Event Published to the others: `UserJoinedFormBuilderEvent` ```json { "id": "Guid", "formId": "Guid", "userId": "Guid", "dateOccurred": "2021-11-22T17:48:48.626Z" } ``` Errors: | Code | # | Notes | | -------------------------- | --- | ------------------------ | | `Hub:UnAuthorized` | | | | `Hub:ChangeFormNotAllowed` | | User resend join request | | `InternalServerError` | | Unknown Error | ### Add Control ```cs Result<AddControlResponse> AddControl(AddControlHubRequest request); ``` Request: ```json { "controlId": "Guid", "controlType": "Page", "parentId": "Guid or null", "order": "1" } ``` Response: ```json { "hasErrors": false, "data": { "control": { } // one of `BasicControl` driven types }, "errors": [ { "code": "...", "description": "..." } ] } ``` Event Published to the others: `ControlAddedEvent` ```json { "id": "Guid", "formId": "Guid", "userId": "Guid", "dateOccurred": "2021-11-22T17:48:48.626Z", "control": { } // one of `BasicControl` driven types } ``` Errors: | Code | # | Notes | | -------------------------- | --- | --------------------------- | | `Hub:UnAuthorized` | | | | `Hub:UnKnownSessionForm` | | User didn't join a form | | `InternalServerError` | | Unknown Error | | `InputValidationError` | (1) | formId is default Guid ⚠️ | | `InputValidationError` | (2) | controlId is default Guid | | `InputValidationError` | (3) | Page with not null parentId | | `InputValidationError` | (4) | Not Page with null parentId | | `Form:FormNotFound` | | ⚠️ | | `Form:ParentNotFound` | | | | `Form:InvalidControlId` | | | | `Form:InvalidControlOrder` | | | ### Move Control ```cs Result<MoveControlResponse> MoveControl(MoveControlHubRequest request); ``` Request: ```json { "controlId": "Guid", "parentId": "Guid or null", // NewParent "order": "1" } ``` Response: ```json { "hasErrors": false, "data": { "controlId": "Guid", "parentId": "Guid or null", "order": "1" }, "errors": [ { "code": "...", "description": "..." } ] } ``` Event Published to the others: `ControlMovedEvent` ```json { "id": "Guid", "formId": "Guid", "userId": "Guid", "dateOccurred": "2021-11-22T17:48:48.626Z", "controlId": "Guid", "parentId": "Guid or null", "order": "1" } ``` Errors: | Code | # | Notes | | -------------------------- | --- | --------------------------- | | `Hub:UnAuthorized` | | | | `Hub:UnKnownSessionForm` | | User didn't join a form | | `InternalServerError` | | Unknown Error | | `InputValidationError` | (1) | formId is default Guid ⚠️ | | `InputValidationError` | (2) | controlId is default Guid | | `InputValidationError` | (3) | Page with not null parentId | | `InputValidationError` | (4) | Not Page with null parentId | | `Form:FormNotFound` | | ⚠️ | | `Form:ControlNotFound` | | | | `Form:ParentNotFound` | | | | `Form:InvalidControlOrder` | | | ### Remove Control ```cs Result<RemoveControlResponse> RemoveControl(RemoveControlHubRequest request); ``` Request: ```json { "controlId": "Guid", "controlType": "Page" } ``` Response: ```json { "hasErrors": false, "data": { "controlId": "Guid", "controlType": "Page", "deletedIds": [ "Guid" ] }, "errors": [ { "code": "...", "description": "..." } ] } ``` Event Published to the others: `ControlRemovedEvent` ```json { "id": "Guid", "formId": "Guid", "userId": "Guid", "dateOccurred": "2021-11-22T17:48:48.626Z", "controlId": "Guid", "controlType": "Page", "deletedIds": [ "Guid" ] } ``` Errors: | Code | # | Notes | | -------------------------- | --- | --------------------------- | | `Hub:UnAuthorized` | | | | `Hub:UnKnownSessionForm` | | User didn't join a form | | `InternalServerError` | | Unknown Error | | `InputValidationError` | (1) | formId is default Guid ⚠️ | | `InputValidationError` | (2) | controlId is default Guid | | `InputValidationError` | (3) | Page with not null parentId | | `InputValidationError` | (4) | Not Page with null parentId | | `Form:FormNotFound` | | ⚠️ | | `Form:ControlNotFound` | | | ### Change Property Value ```cs Result<ChangePropertyValueResponse> ChangePropertyValue(ChangePropertyValueHubRequest request); ``` Request: ```json { "controlId": "Guid", "entityType": "Control", // Form, Control "property": { "path": ".style.color", "value": "\"red\"", // the value should be a valid serialzied json string } } ``` Response: ```json { "hasErrors": false, "data": { "controlId": "Guid", "property": { "path": ".style.color", "value": "\"red\"", // the value should be a valid serialzied json string } }, "errors": [ { "code": "...", "description": "..." } ] } ``` Event Published to the others: `PropertyValueChangedEvent` ```json { "id": "Guid", "formId": "Guid", "userId": "Guid", "dateOccurred": "2021-11-22T17:48:48.626Z", "controlId": "Guid", "property": { "path": ".style.color", "value": "\"red\"", // the value should be a valid serialzied json string } } ``` Errors: | Code | # | Notes | | -------------------------- | --- | --------------------------- | | `Hub:UnAuthorized` | | | | `Hub:UnKnownSessionForm` | | User didn't join a form | | `InternalServerError` | | Unknown Error | | `InputValidationError` | (1) | formId is default Guid ⚠️ | | `InputValidationError` | (2) | controlId is default Guid | | `InputValidationError` | (3) | Page with not null parentId | | `InputValidationError` | (4) | Not Page with null parentId | | `Form:FormNotFound` | | ⚠️ | | `Form:ControlNotFound` | | | | `Form:InvalidProprtyPath` | | | ### Revert History > TODO: Not Implemented yet ## Rest APIs (HTTP) ### Create New Form ```txt POST {backend-url}/api/Forms/Create { "name": "..." } ``` Response: ```json { "isDeleted": true, "createdAt": "2021-12-01T01:10:06.055Z", "createdBy": "string", "updatedAt": "2021-12-01T01:10:06.055Z", "updatedBy": "string", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "lastPublishedVersionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "draftedSchema": { "isDeleted": true, "createdAt": "2021-12-01T01:10:06.055Z", "createdBy": "string", "updatedAt": "2021-12-01T01:10:06.055Z", "updatedBy": "string", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "lastAppliedEventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "schema": {}, "status": 0, "concurrencyStamp": "string" }, "draftEvents": [ { "isDeleted": true, "createdAt": "2021-12-01T01:10:06.055Z", "createdBy": "string", "updatedAt": "2021-12-01T01:10:06.055Z", "updatedBy": "string", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "eventData": {} } ], "schemaVersions": [ { "isDeleted": true, "createdAt": "2021-12-01T01:10:06.055Z", "createdBy": "string", "updatedAt": "2021-12-01T01:10:06.055Z", "updatedBy": "string", "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "schema": {} } ] } ``` ### List All Forms ```txt GET {backend-url}/api/Forms/GetAll ``` Response: ```json [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "string", "lastPublishedVersionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "createdAt": "2021-11-22T17:50:31.036Z", "createdBy": "string", "updatedAt": "2021-11-22T17:50:31.036Z", "updatedBy": "string" } ] ``` ### Get Form Json Schema ```txt GET {backend-url}/api/Forms/GetSchema/{formId: GUID} ``` Response: ```json { "schema": { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "templateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "lastAppliedEventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "themeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "status": 0, "settings": { "format": 0, "enableScoreCalculation": true, "expirationDate": "2021-12-13T17:39:13.105Z", "defaultLanguage": 0, "availableLanguages": [ 0 ] }, "properties": { "navigation": { "submit": "string", "next": "string", "back": "string", "backVisibility": true, "localization": { "additionalProp1": { "submit": "string", "next": "string", "back": "string" }, "additionalProp2": { "submit": "string", "next": "string", "back": "string" }, "additionalProp3": { "submit": "string", "next": "string", "back": "string" } } }, "campaign": { "header": { "logo": "string", "title": "string", "description": "string", "showQuestionsCount": true, "localization": { "additionalProp1": { "title": "string", "description": "string" }, "additionalProp2": { "title": "string", "description": "string" }, "additionalProp3": { "title": "string", "description": "string" } } }, "footer": { "logo": "string", "title": "string", "description": "string", "showQuestionsCount": true, "localization": { "additionalProp1": { "title": "string", "description": "string" }, "additionalProp2": { "title": "string", "description": "string" }, "additionalProp3": { "title": "string", "description": "string" } } }, "welcome": { "logo": "string", "title": "string", "description": "string", "showQuestionsCount": true, "localization": { "additionalProp1": { "title": "string", "description": "string" }, "additionalProp2": { "title": "string", "description": "string" }, "additionalProp3": { "title": "string", "description": "string" } } }, "submissionMessage": { "logo": "string", "title": "string", "description": "string", "showQuestionsCount": true, "localization": { "additionalProp1": { "title": "string", "description": "string" }, "additionalProp2": { "title": "string", "description": "string" }, "additionalProp3": { "title": "string", "description": "string" } } } } }, "warningMsgs": { "required": { "fieldRequired": "string", "oneFieldPerFormRequired": "string" }, "textBox": { "minimumCharacterLength": "string", "maximumCharacterLength": "string", "minimumWordLength": "string", "maximumWordLength": "string", "email": "string", "url": "string", "alphapetic": "string", "alphaNumeric": "string", "numeric": "string", "custom": "string" }, "textArea": { "minimumCharacterLength": "string", "maximumCharacterLength": "string", "minimumWordLength": "string", "maximumWordLength": "string" }, "number": { "minimumValue": "string", "maximumValue": "string", "minimumDigits": "string", "maximumDigits": "string" }, "email": { "validEmail": "string", "notMatchEmail": "string" } }, "fields": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "templateQuestionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "type": 0, "parentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "order": "string", "properties": { "labelPosition": 0, "hidden": true, "label": "string", "sublabel": "string", "tooltip": "string", "localization": { "additionalProp1": { "label": "string", "sublabel": "string", "tooltip": "string" }, "additionalProp2": { "label": "string", "sublabel": "string", "tooltip": "string" }, "additionalProp3": { "label": "string", "sublabel": "string", "tooltip": "string" } } }, "styles": { "labelStyle": { "color": "string", "backgroundColor": "string", "fontSize": 0, "weight": 0 } } } ] } } ``` Errors: | Code | # | Notes | | -------------------------- | -- | ------------- | | `InternalServerError` | | Unknown Error | | `Form:FormNotFound` | | | | `Form:LoadingTimeout` | | |