OWASP Top 10 Explained: SQL Injection

Cyberattacks are a common and permanent threat. This paper is the first in a series about cybersecurity.

The aim is to provide software engineers with an understanding of the main threats and how to address them. Most exploits are based on basic errors.

Architecture: Software Cost Estimation

Estimating workloads is crucial in mastering software development. This can be achieved either as an ongoing development part of agile teams or in response to tenders as a cost estimate before migration, among other ways.

The team responsible for producing the estimate regularly encounters a considerable workload, which can lead to significant time consumption if the costing is not conducted using the correct methodology.

Architecture Style: Modulith (vs. Microservices)

Modulith architecture is a style of software design that emphasizes modularity within a monolithic application. It aims to combine the simplicity and straightforward deployment model of a monolithic architecture with the modularity and maintainability typically associated with microservices.

In a modulith, the application is structured as a collection of loosely coupled modules, each encapsulating a specific business capability or domain. These modules interact with each other through well-defined interfaces, yet they are deployed as a single unit, similar to a traditional monolithic application.

AI/Machine Learning Techniques: The Cheat Sheet

Welcome to a straightforward guide on machine learning. This paper is a summary that breaks down the big ideas of machine learning into easy-to-understand parts. Think of it as a quick reference or a cheat sheet that helps you come to grips with how machines learn to make sense of data, make predictions, and even create new things. We’ll look at different ways machines can be taught, how they figure out patterns on their own, and how they make smart decisions. Whether you’re new to the world of AI or just need a refresher, this paper aims to make the complex world of machine learning a little easier to navigate.

machine learningSupervised

Supervised Learning involves training algorithms with labeled data, where each input is paired with the correct output. This method teaches algorithms to map inputs to outputs, learning from clear examples. As it processes more data, the algorithm recognizes patterns and improves its predictions for new, unseen data.

Navigating the CAP Theorem: In Search of the Perfect Database

The CAP Theorem is a foundational concept in the world of distributed computing, particularly for databases. Developed by Eric Brewer, it challenges us to understand that in any network of databases, we can’t have the perfect combination of three key features at the same time: Consistency (all nodes show the same data), Availability (every request receives a response), and Partition Tolerance (the system continues to operate despite network failures).

Understanding Each Aspect of CAP

1. Consistency

This is about having the same data across all system parts at any given time.

C4 Model Perspective: The Different Types of Software Architects

Software architecture is a critical aspect of software development. It involves the high-level structuring of software systems to meet technical and business requirements. Software architects play a pivotal role in this process by making design choices, dictating technical standards, and leading implementation efforts. 

This paper proposes a description of different architecture types. However, as this has been done many times before, I want to add the perspective of the C4 model to help understand who will intervene and at each level and with whom they will have to interact.

Architecture Patterns: Sharding

What Is Sharding?

Sharding, a database architecture pattern, involves partitioning a database into smaller, faster, more manageable parts called shards. Each shard is a distinct database, and collectively, these shards make up the entire database. Sharding is particularly useful for managing large-scale databases, offering significant improvements in performance, maintainability, and scalability.

Key Characteristics

Data Distribution: Shards can be distributed across multiple servers, reducing the load on any single server and improving response times.

Architecture Patterns: Publish/Subscribe

The Publish/Subscribe (Pub/Sub) pattern is a widely-used software architecture paradigm, particularly relevant in the design of distributed, messaging-driven systems. The communication framework is decoupled, scalable, and dynamic, making it useful for addressing complex software requirements in modern application development.

At its core, the Pub/Sub pattern is about decoupling the message producer (publisher) from the message consumer (subscriber). In this framework, publishers broadcast messages without the knowledge of subscribers, and subscribers receive messages based on their interest without knowing about publishers. This decoupling is facilitated through a central component known as the message broker or event bus, which manages the delivery of messages.

Architecture Patterns : Data-Driven Testing

What Is Data-Driven Testing? 

Data Driven Testing is a concept in software testing that emphasizes the separation of test data from the test logic or scripts. In this approach, test scripts are designed to read test parameters and input data from external sources like databases, XML files, Excel sheets, Json files, or CSV files. This design allows a single test script to execute tests for a vast array of data sets, improving test efficiency and coverage.

The significance of DDT lies in its ability to automate and streamline the testing process, particularly in scenarios where application behavior depends heavily on varied input data. This approach is essential in validating and verifying applications that handle extensive and diverse datasets.

Evolution of Software Architecture: From Monoliths to Microservices and Beyond

In the vast and ever-evolving domain of software development, the architecture of software systems stands as a pivotal aspect, shaping not only how applications are built and maintained but also how they adapt to changing technological landscapes and business needs. This paper embarks on an exploratory journey through the evolution of software architecture, tracing its progression from the early days of monolithic designs to the contemporary era of microservices and serverless architectures. We delve into the fundamental shifts in architectural patterns, examining how each has been influenced by and has responded to the advancements in technology, the growing complexity of applications, and the evolving requirements of businesses.

Our exploration begins with monolithic architectures, the bedrock of early software development, characterized by their unified and indivisible nature. We then transition to modular designs, heralding a new era of software architecture that emphasizes separation of concerns and encapsulation. Following this, we explore the emergence of Service-Oriented Architecture (SOA), a paradigm shift that underscores service reuse and interoperability. The narrative progresses to the rise of microservices architecture, a fine-grained approach building on the principles of SOA but with a greater emphasis on independence and scalability. Our journey extends to the realm of serverless computing, a paradigm that further abstracts and simplifies (or not ?) architectural complexities.

Architecture Method: C4 Model

What Is the C4 Model?

The C4 model is a framework used in software engineering to visualize and describe the architecture of software systems. Developed by Simon Brown, it stands for “Context, Containers, Components, and Code,” which represents different levels of granularity for depicting a system’s architecture.

Context

The purpose of this section is to offer a global perspective of the system, highlighting its interactions and connections with external entities such as users, emailing systems, and other external systems. Here are some key points:

Architecture Approach: Domain-Driven Design (DDD)

What Is Domain-Driven Design (DDD)?

DDD is a software development approach that focuses on aligning complex software designs with business needs. It advocates for a deep connection between the implementation and the core business concepts. This alignment is achieved through several key concepts that guide the design and development process.

Key Concepts

Domain: The term “domain” refers to the specific business area or sphere of knowledge and activity around which the software is built. It encompasses the business’s problems, operations, logic, and rules. Understanding the domain is crucial, as the software’s purpose is to address and solve real-world problems within this domain. It may also contain sub-domains.

Architecture Patterns: API Gateway

What Is an API Gateway?

An API Gateway is a tool that acts as an intermediary for requests from clients seeking resources from servers or microservices. It manages, routes, aggregates, and secures the API requests.

Like previous patterns we have explored, this is often described as a “microservices context” pattern, but this is not necessarily the case. It could be worth using in many “not microservices” cases and sometimes shouldn’t be used in microservices.

Architecture Patterns: Strangler Pattern

The Strangler Pattern, first described by Martin Fowler, is a software architectural pattern that describes a method of gracefully migrating a legacy system incrementally rather than in a big-bang approach. It is named after the Strangler Fig, a type of vine that slowly grows on a tree and eventually replaces it. Similarly, in the software context, the Strangler Pattern involves building a new system around the boundaries of the old system, allowing you to slowly replace parts of the old system with components of the new system over time.  

Many Software engineers will be confronted with system migration in their careers; technology is growing faster, and humans need time to adapt and maintain their systems, which can become old sometimes even before they have time to finish it. A strangler pattern is an approach that allows migration without a big bang, which can be very stressful for teams and is often condemned to failure. This pattern is very efficient in the context of large systems because it allows people to gain confidence in the ability to make the migration, providing a multitude of small successes that are much harder to achieve in a one-shot.

Architecture Patterns: The Circuit-Breaker

In the world of distributed systems, the likelihood of components failing or becoming unresponsive is higher compared to monolithic systems. Given the interdependence of microservices or modules in a distributed setup, the failure of one component can lead to cascading failures throughout the system, potentially causing the entire system to malfunction or shut down. Therefore, resilience — the ability of a system to handle and recover from failures — becomes critically important in distributed environments.

Much like how an electrical circuit breaker prevents an overload by stopping the flow of electricity when excessive current is detected, the Circuit Breaker pattern in software engineering stops the flow of requests to a service when the number of failures exceeds a predefined threshold. This ensures that a failing service doesn’t continue receiving traffic until it recovers, preventing further strain and potential cascading failures.

Architecture Anti-Patterns: The DARK Side of the Architect

Amid the realm of logic and structured thought, architects, much like the mythical creatures of old, harbor a shadowy underside. Like the ancient legends where heroes have their flaws and palaces haunted chambers, architectural designs, no matter how splendid, possess pitfalls and lurking dangers. The illustrious facades of our software edifices can sometimes obscure the eerie passages and cobwebbed corners inherent within. Like everybody, architects have a dark side, a realm where patterns and practices, if not wielded with caution, can spiral into chilling tales of system horrors. In this paper, we shall venture into this enigmatic domain, shedding light on the specters that haunt our architectural decisions and understanding how to exorcise the demons that threaten our digital sanctuaries.

Multi-Tenant: The Haunted Mansion

The Overcrowded Ghost Party

Not separating tenant data appropriately can lead to data leaks between tenants, potentially violating data protection laws.

The Outbox Pattern

In the intricate tapestry of distributed systems, particularly within the microservices architecture, the challenges of reliable message delivery and data consistency are pervasive and demanding. The outbox pattern, often cited in the exclusive realm of microservices, emerges from a crucible where ensuring the atomicity of local database transactions and publishing messages to other services is paramount. Amidst the web of inter-service communication, it emerges as a stratagem to ensure that messages are not forgotten in the midst of outages or network inconsistencies.

However, the adaptability and utility of the outbox pattern transcends its microservices origins, weaving into its fabric principles that are universally applicable to diverse architectural contexts. This paper embarks on a journey to demystify the outbox pattern, not as a microservices-specific tool, but as a robust architectural pattern with the potential to improve reliability and consistency across disparate and distributed computing environments.

Selenium Versus Karate: A Concrete Comparative Approach

In the world of software architecture, which is still in its infancy in absolute terms, change is still rapid and structural. Deep paradigms can be overturned, changing the structure of information systems. As coupling has become a key issue for many information systems, new architectures have emerged, notably SOA (Service Oriented Architecture), followed by Microservices. These two fairly widespread architectures certainly make it
possible to solve coupling problems, but as always there are certain trade-offs to be made. The complexity of testing is one of them.

Like a balanced equation, an information system is an equivalence between a technical expression and a functional expression, and if one changes, we need to be able to guarantee the validity of the equivalence between the two. To attain this, we need to be able to test all parties using tools that can establish this equality. When releasing a new version of a microservice, it’s fairly easy to run unit and even integration tests before and during deployment to validate its internal operation.