{"id":8906,"date":"2024-05-08T06:07:51","date_gmt":"2024-05-08T06:07:51","guid":{"rendered":"https:\/\/modeling-languages.com\/?p=8906"},"modified":"2024-05-08T06:12:05","modified_gmt":"2024-05-08T06:12:05","slug":"generating-software-backend-lowcode","status":"publish","type":"post","link":"https:\/\/modeling-languages.com\/generating-software-backend-lowcode\/","title":{"rendered":"Generating a full software backend with the low-code BESSER platform"},"content":{"rendered":"<p>The popularity and adoption of low-code tools and frameworks continue to rise. The main advantage of these tools is the reduction in time for developing and deploying custom applications thanks to the use of automatic <a href=\"https:\/\/modeling-languages.com\/executable-models-vs-code-generation-vs-model-interpretation-2\/\" target=\"_blank\" rel=\"noopener\">code-generators<\/a>. For example, <a href=\"https:\/\/modeling-languages.com\/besser-released-open-source-low-code-tool\/\">BESSER<\/a>, an open-source low-code platform for smart software development, offers code generators for various technologies such as SQLAlchemy, Django, Python, and more.<\/p>\n<p>And today, we release an even more interesting generator that, instead of targeting a single artefact, aims to <strong>generate the full backend of your application!<\/strong> This new feature is now available in the <a href=\"https:\/\/github.com\/BESSER-PEARL\/BESSER\" target=\"_blank\" rel=\"noopener\">latest release<\/a> of the platform.<\/p>\n<h2>Step 1 &#8211; Model your application with BESSER<\/h2>\n<p>BESSER features a modeling language called B-UML for specifying different aspects of a domain or application. B-UML (short for BESSER\u2019s Universal Modeling Language) is heavily inspired by UML but does not aim to be fully compliant with it. In other words, it is composed of a set of sublanguages that modelers can choose to &#8216;activate&#8217; for a given project depending on their modeling needs. Currently, the types of models that can be created in BESSER include structural models, object models, graphical user interface models, and OCL specifications (you can find the description in <a href=\"https:\/\/besser.readthedocs.io\/en\/latest\/index.html\" target=\"_blank\" rel=\"noopener\">BESSER&#8217;s documentation<\/a>).<\/p>\n<p>To generate the backend software for your application, you need to specify a structural model describing the domain concepts in a class diagram.<\/p>\n<p>BESSER can understand structural models built with <a href=\"https:\/\/plantuml.com\/\" target=\"_blank\" rel=\"noopener\">PlantUML<\/a>. So, we are going to implement the example model in Figure 1 (the typical model of Library, Book, and Author) to generate its full backend software. You can refer to <a href=\"https:\/\/besser.readthedocs.io\/en\/latest\/buml_language\/model_building\/plantuml_structural.html\" target=\"_blank\" rel=\"noopener\">this documentation<\/a> for guidance on utilizing PlantUML models within BESSER.<\/p>\n<div id=\"attachment_8916\" style=\"width: 594px\" class=\"wp-caption aligncenter\"><a style=\"font-weight: bold;\" href=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/domain_model_plantUML.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-8916\" class=\"wp-image-8916 \" src=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/domain_model_plantUML.png\" alt=\"\" width=\"584\" height=\"416\" srcset=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/domain_model_plantUML.png 584w, https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/domain_model_plantUML-480x342.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 584px, 100vw\" \/><\/a><p id=\"caption-attachment-8916\" class=\"wp-caption-text\">Figure 1. Domain model<\/p><\/div>\n<p>&nbsp;<\/p>\n<h2>Step 2 &#8211; Generate your Backend<\/h2>\n<p>To manage the data conforming to the previous schema you will need at least database where that data can be stored and retrieved. Obviously, the schema of such database will be generated from the structural model. But a database is not enough, you will probably also want to provide a REST API access to the data so you can better control who and how access the data. And not any API but one that has some validation for the input data before trying to save it in the database in order to minimize errors.<\/p>\n<p>Well, our new BESSER version provides all this: our Backend Generator combines multiple specialized generators from the BESSER suite to create a full backend for you, as shown in Figure 2. More specifically, our backend generator facilitates the creation of dynamic and scalable API endpoints thanks to the REST API Generator (relying on the <a href=\"https:\/\/fastapi.tiangolo.com\/\" target=\"_blank\" rel=\"noopener\">FastAPI<\/a> framework), efficient ORM transformation for database interactions thanks to the SQL Alchemy Generator, and robust data validation thanks to the <a href=\"https:\/\/docs.pydantic.dev\/latest\/\" target=\"_blank\" rel=\"noopener\">Pydantic<\/a> Generator, ensuring data integrity and backend security.<\/p>\n<div id=\"attachment_8911\" style=\"width: 680px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/back_generator.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-8911\" class=\"wp-image-8911 size-full\" src=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/back_generator.png\" alt=\"\" width=\"670\" height=\"351\" srcset=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/back_generator.png 670w, https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/back_generator-480x251.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 670px, 100vw\" \/><\/a><p id=\"caption-attachment-8911\" class=\"wp-caption-text\">Figure 2. Overview of the BESSER backend generator<\/p><\/div>\n<p>Running the backend generator is similar to how you run any other generator:<\/p>\n<div id=\"attachment_8910\" style=\"width: 857px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/code_gen.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-8910\" class=\"wp-image-8910\" src=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/code_gen-1024x150.png\" alt=\"\" width=\"847\" height=\"124\" \/><\/a><p id=\"caption-attachment-8910\" class=\"wp-caption-text\">Listing 1. Execution of the backend code generator<\/p><\/div>\n<p>You can tailor the code generation process to meet your application&#8217;s specific needs by selecting appropriate HTTP methods like GET, POST, PUT, and DELETE. This selective approach helps generate only the necessary API components, enhancing efficiency. If your B-UML model includes read-only classes, the generator automatically omits PUT and DELETE methods, maintaining the immutability of certain data elements as defined in your model.<\/p>\n<p>The <em>nested_creations<\/em> parameter further refines API handling of entity relationships in requests. When enabled, it allows the API to link existing entities using identifiers and create new nested entities within the same request. If disabled, the API restricts itself to linking existing entities, simplifying interactions but limiting flexibility. The default setting is disabled, focusing on straightforward data linkages.<\/p>\n<p>For the Library example previously described, the generator will create three different files using different components of the generators.<\/p>\n<ol>\n<li>The main file generated is <strong><em>main_api.py<\/em><\/strong>, which includes the initialization of the database and the REST API endpoints defining how the server responds to client requests.<\/li>\n<li>The second one is the <strong><em>sql_alchemy.py<\/em><\/strong> file containing the SQLAlchemy ORM models, which establish mappings between Python classes and database tables.<\/li>\n<li>And the final one, the <strong><em>pydantic_classes.py<\/em><\/strong> file crucial for data validation and serialization.<\/li>\n<\/ol>\n<p>Once <strong><em>main_api.py<\/em><\/strong> is launched, the server becomes operational, allowing clients to interact with the backend service through the specified REST API endpoints. Additionally, the <em><strong>openapi_specs.json<\/strong><\/em> file is generated. This JSON file contains the documentation following the <a href=\"https:\/\/swagger.io\/specification\/\" target=\"_blank\" rel=\"noopener\">OpenAPI specification<\/a> to describe the structure and behavior of the API, including the list of available endpoints, the parameters they accept, the types of data they expect, the possible response codes and other important details. Figure 3 shows an excerpt of the <em>OpenAPI<\/em>\u00a0specification generated for the Library example.<\/p>\n<div id=\"attachment_8922\" style=\"width: 500px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/open_api.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-8922\" class=\"wp-image-8922 size-full\" src=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/open_api.png\" alt=\"\" width=\"490\" height=\"737\" srcset=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/open_api.png 490w, https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/open_api-480x722.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 490px, 100vw\" \/><\/a><p id=\"caption-attachment-8922\" class=\"wp-caption-text\">Figure 3. <em>OpenAPI<\/em> specification generated<\/p><\/div>\n<p>With the server up and running, and leveraging the OpenAPI specification, you can access the interactive API documentation provided by <a href=\"https:\/\/github.com\/swagger-api\/swagger-ui\" target=\"_blank\" rel=\"noopener\">Swagger UI<\/a>. Figure 4 displays a snapshot of the graphical interface, through which you can also explore available endpoints, accepted parameters, response codes, and other details.<\/p>\n<div id=\"attachment_8923\" style=\"width: 1001px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/fast_api.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-8923\" class=\"wp-image-8923 size-full\" src=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/fast_api.png\" alt=\"\" width=\"991\" height=\"710\" srcset=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/fast_api.png 991w, https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/fast_api-980x702.png 980w, https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/fast_api-480x344.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 991px, 100vw\" \/><\/a><p id=\"caption-attachment-8923\" class=\"wp-caption-text\">Figure 4. Interactive API documentation<\/p><\/div>\n<p><strong>An SQLite database is automatically constructed<\/strong> according to the models produced in the <strong><em>sql_alchemy.py <\/em><\/strong>file. Figure 5 presents a screenshot of the database generated for our Library example with some books entries created.<\/p>\n<div id=\"attachment_8918\" style=\"width: 975px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/lib_database.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-8918\" class=\"wp-image-8918 size-full\" src=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/lib_database.png\" alt=\"\" width=\"965\" height=\"240\" srcset=\"https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/lib_database.png 965w, https:\/\/modeling-languages.com\/wp-content\/uploads\/2024\/05\/lib_database-480x119.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 965px, 100vw\" \/><\/a><p id=\"caption-attachment-8918\" class=\"wp-caption-text\">Figure 5. Generated database<\/p><\/div>\n<p>&nbsp;<\/p>\n<h2>What&#8217;s next<\/h2>\n<p>BESSER strives to be an open-source low-code platform for developing smart software. The code generator presented here is another step forward for BESSER in that regard. This customizable generator provides a solution to streamline the development of backend applications, including their database, REST API endpoints, and OpenAPI specification. With this solution, we showcase BESSER&#8217;s ability not only to build new code generators but also its capacity to reuse existing generators as part of a comprehensive solution that involves code generation for various technologies.<\/p>\n<p>We have plenty of ideas about what could be next, but we would love to hear from you as well. What would you like to see in the next BESSER release?????<\/p>\n<span class=\"et_bloom_bottom_trigger\"><\/span>","protected":false},"excerpt":{"rendered":"<p>Would you like to automatically get a fully fledged backend (database, REST API, validators,&#8230;) from a single model? You&#8217;ve come to the right place<\/p>\n","protected":false},"author":99,"featured_media":8929,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","_has_post_settings":[],"footnotes":""},"categories":[208,36],"tags":[853,912,906,844,206],"hashtags":[],"class_list":["post-8906","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mdd-code-generation","category-databases","tag-api","tag-backend","tag-besser","tag-database","tag-validation"],"_links":{"self":[{"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/posts\/8906","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/users\/99"}],"replies":[{"embeddable":true,"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/comments?post=8906"}],"version-history":[{"count":13,"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/posts\/8906\/revisions"}],"predecessor-version":[{"id":8927,"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/posts\/8906\/revisions\/8927"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/media\/8929"}],"wp:attachment":[{"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/media?parent=8906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/categories?post=8906"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/tags?post=8906"},{"taxonomy":"hashtags","embeddable":true,"href":"https:\/\/modeling-languages.com\/wp-json\/wp\/v2\/hashtags?post=8906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}