The Streams platform leans heavily on domain-driven design (DDD). We call these domain abstractions streams
, hence our namesake.
An example could be configuring a domain model (a stream) for a website's pages, users of an application, or feedback submissions from a form. Streams describe your data structures.
Using JSON files, you can define stream configurations in the streams/
directory. The filenames serve as the stream's id
.
It is highly encouraged to use the plural form of a noun when naming Streams—for example, contacts and people. Also, naming conventions like business_contacts
or neat-people
work well.
├── streams/
│ ├── users.json
│ ├── pages.json
│ └── contacts.json
To get started, you need only specify the id
, which is the filename itself, and some fields
to describe the domain object's structure.
Let's create a little stream to hold information for a simple CRM.
// streams/contacts.json
{
"name": "Contacts",
"description": "A simple address book.",
"config": {
"source": {
"type": "filebase",
"filename": "streams/data/contacts",
"format": "json"
},
"abstract": "Streams\\Core\\Entry\\Entry",
"criteria": "Streams\\Core\\Criteria\\Criteria",
"repository": "Streams\\Core\\Repository\\Repository",
"collection": "Illuminate\\Support\\Collection",
},
"fields": {
"name": "string",
"email": "email",
"company": {
"type": "relationship",
"config": {
"related": "companies"
}
}
}
}
Fields are an essential descriptor of the domain object. They describe what properties the domain object will have and how they work. Field types control things like accessors, data mutation, and casting.
The field configuration keys serve as a handle
, which you can use to reference the field later. So, for example, you may access the above contact fields like this:
$entry->email;
$entry->company->email;
Streams can simplify routing by defining associated routes in their definition.
// streams/contacts.json
{
"routes": {
"index": "contacts",
"view": "contacts/{id}"
}
}
You can also use an array to include other route options.
// streams/contacts.json
{
"routes": {
"contact": {
"csrf": false,
"uri": "form/{entry.email}"
}
}
}
Streams simplifies validation by defining validation in their definition.
// streams/contacts.json
{
"rules": {
"name": [
"required",
"max:100"
],
"email": [
"required",
"email:rfc,dns"
],
"company": "required|unique"
}
}
Specify the Laravel policy to use for security.
// streams/contacts.json
{
"policy": "App\\Contacts\\ContactPolicy"
}
Streams provides a touch-free caching system you can define in the configuration.
// streams/contacts.json
{
"cache": false,
"ttl": 1800 // 30 minutes
}
Sources define the source information for entry data which you can define in the configuration.
// streams/contacts.json
{
"source": {
"type": "filebase",
"format": "md"
}
}
Domain entities are called entries
within the Streams platform. A stream defines entry attributes, or fields
, that dictate the entry's properties, data-casting, and more.
The abstract parameter defines the class to use when constructing entry instances.
// streams/contacts.json
{
"abstract": "App\\Contacts\\Contact"
}
When defining Elqouent stream sources, the sources model will be used as the abstract.
The criteria parameter defines the class to use when building entry queries.
// streams/contacts.json
{
"criteria": "App\\Contacts\\ContactCriteria"
}
The repository parameter defines the repository class to use for the stream entries.
// streams/contacts.json
{
"repository": "App\\Contacts\\ContactRepository"
}
You can use JSON file references within stream configurations to point to other JSON files using the @
symbol followed by a relative path to the file. In this way, you can reuse various configuration information or tidy up larger files. The referenced file's JSON data directly replaces the reference.
// streams/contacts.json
{
"name": "Contacts",
"fields": "@streams/fields/contacts.json"
}
// streams/fields/contacts.json
{
"name": "string",
"email": "email",
"company": {
"type": "relationship",
"stream": "company"
}
}
A stream can extend
another stream, which works like a recursive merge.
// streams/family.json
{
"name": "Family Members",
"extend": "contacts",
"fields": {
"relation": {
"type": "select",
"config": {
"options": {
"mother": "Mother",
"father": "Father",
"brother": "Brother",
"sister": "Sister"
}
}
}
}
}
In the above example, all contacts
fields are available to you, as well as the new relation
field.
$entry->email; // The email value.
$entry->relation; // The relation value.
You can configure the flat-file database as well as other sources for storing data including any Laravel database. No code changes required.
A blank TALL-stack Laravel project with Streams.
The fundamental features and utilities offered by the Streams platform.
A universal and extensible RESTful API for Streams.
Extensible, user-friendly, and performant control panel, components, and services.
Dev tooling for Laravel Streams.