The (unnamed) language
(unnamed) is a backend language + framework developed as a hobby. Files written in (unnamed) are meant to deliver a consistent backend that can be interpreted by any number of consumers.
Jump to syntax and use cases →Motivations
Developing systems at scale is hard. A big hurdle when it comes to backend development is how easily complexity and bias gets introduced into the mix. This can create a lot of problems — namely in more overhead costs and a worse experience for your end-user.
This project intends to solve some of those issues by giving an easy-to-adopt framework built on principles that exist in fault-tolerant and performant systems today. This way developers start their projects with scale in mind, instead of wasting time doing it later.
"My project doesn't need to scale!"
You're right! A lot of times the traditional way of doing things makes sense especially when you don't expect to have thousands of users. Like any framework, (unnamed) has its uses but that doesn't mean its applicable for every project under the sun. However, a system utilizing (unnamed) serves as the basis for your backend that is detracted from the bias of implementing it in any one framework or backend (?).
Syntax
Files written in (unnamed) mainly serve one purpose — to describe the components of an area of a system, called a context, in the system at large, known as a domain.
context acme.product {
type Product {
name String
price Double
}
type LineItem {
product Product
quantity Int
}
}
You should have one context for each meaningful area of interest in a domain (think of it like a microservice). This way of modelling systems is a way to represent meaningful real-world concepts relevant to the domain without including technical jargon that will confuse non-technical stakeholders.
For instance if you're building a system for doing ecommerce, these are some contexts you'd need to implement:
- Product
- Cart
- Checkout
- Order
- Fulfillment
Objects
… are the things describing a context
Interfaces
Methods
Use cases
As mentioned above, contexts are intended to be used by multiple consumers. For instance, consider the following context.
context acme.product {
entity Product {
product_id String
name String
price Double
}
query FetchProducts() []Product {
return Product.query()
}
query FetchProduct(product_id: String) Product {
return Product.findOne({ product_id: product_id })
}
command DeleteProduct(product_id: String) {
Product.findOne({ product_id: product_id }).delete()
}
}
You could then use this context:
In a React component
import { useQuery } from '(unnamed)';
import { FetchProducts } from 'acme.product';
export function CategoryPage() {
const { data, loading, error } = useQuery(FetchProducts, {});
return (
// ...a bunch of products
);
}
In a REST/OpenAPI definition
endpoints:
/api/products:
get:
query: acme.product.FetchProducts
/api/products/{productID}:
get:
query: acme.product.FetchProduct
body: $path.productID
delete:
command: acme.product.DeleteProduct
body: $path.productID
As a graph
Resources
Domain-Driven-Design, Reactive Architecture, and Eventual Consistency