Release NotesA React + ASP.NET Core Framework

logo

Deliver applications faster with the Xams Framework

All in One

Unified Coding Framework

Use an architecture that makes writing business logic and managing data easy and enjoyable. Xams abstracts away the complexity of common application features so you can focus on building your app.

Unified Endpoint
Never write another API endpoint. Xams uses a single set of endpoints for all your data.

Learn more

Security Model
A flexible security model defines who can access your data and what they can do with it.

Learn more

Smart UI Components
React components know how to bind to the Entity Framework and display your data.

Learn more

Service Layer
A well organized service layer makes it easy to write business logic that executes on any CRUD operations.

Learn more

Scheduled Jobs
Easily and quickly write scheduled jobs that run in the background.

Learn more

SQL-Like Queries
Write SQL-like queries from javascript.

Learn more

Entity Framework

A Single Model

Xams uses attributes on your model classes to determine whats exposed to the client. This allows you to have a single model that is used for both the view and controller.

[Table(nameof(Widget))]
public class Widget : BaseEntity
{
public Guid WidgetId { get; set; }
[UIRequired] // This will be required by the UI and server
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
[UIHide] // This will never be available in the UI
public string CouponCode { get; set; }
}

CRUD

Unified Endpoint

Xams has 10 endpoints that perform all CRUD operations on your data, provide entity metadata, and retrieve permissions. There is no need to scaffold new endpoints.

CRUD operations.
Create, Read, Update, Delete, Upsert, and Bulk—are used to interact with all entities. Data can be sent in batches or as a single bulk transaction.
Metadata.
The metadata endpoint provides information about your models, including fields, types, and attributes.
Permissions.
The permissions endpoint enables you to check whether a user has access to a specific entity or action. This is useful for determining what should be visible in the UI.
Endpoints Screenshot

Security

Permissions

Permissions can be set from the Admin Dashboard. You can define who can access which data and what actions they are allowed to perform.

Users.
Users can be assigned to roles and teams. They inherit the permissions of the roles and teams to which they are assigned.
Teams.
Users can be assigned to teams. Roles can be configured to allow users to see only the records for their teams.
Roles.
Roles are assigned permissions. These permissions determine which actions can be performed on specific entities.
Permissions Screenshot

Management

Admin Dashboard

Manage data for all your entities, configure security settings, and monitor job processes.

Entities
Search, create, update, and delete records for all your entities.
Config Data
Export and Import your data for any or all entities.
Jobs
Trigger jobs manually and monitor job processes.
Dashboard Screenshot

Query

Javascript Queries

You can query your data from the frontend using SQL-like syntax. This allows for complex filters, ordering, joins, and left joins. Enable denormalization to return the data in a nested format.

// Select all columns from the User table
let readRequest = new Query(["*"])
.from("User").top(10).page(1).distinct()
.join("User.UserId", "Account.OwnerId", "acc", ["AccountName"])
.where("PurchaseCount", ">=", "10")
.toReadRequest();

Logic

Service Logic

Easily write service logic for specific entities by using the IServiceLogic interface and the ServiceLogic attribute.

Entity Name.
Specify the entity name for the service logic to execute on, or use '*' for all entities.
Data Operation.
Specify whether the service logic should execute on a Create, Read, Update, or Delete operation.
Logic Stage.
Specify whether the logic should run before or after the data operation.
[ServiceLogic(nameof(Widget),
DataOperation.Create | DataOperation.Update,
LogicStage.PreOperation)]
public class WidgetService : IServiceLogic
{
public async Task<Response<object?>> Execute(ServiceContext context)
{
// Get the widget to be created or updated
Widget widget = context.GetEntity<Widget>();
// Do some stuff
return ServiceResult.Success();
}
}

Jobs

Scheduled Jobs

Use the IServiceJob interface and ServiceJob attribute to turn any class into a scheduled job.

Intervals.
Scheduled jobs can be set to run at intervals, such as every 5 minutes, every hour, or every day.
Time of Day.
Scheduled jobs can be set to run at specific times of day, such as 3:00 AM or 8:00 PM.
Specific Days.
Scheduled jobs can be set to run on specific days of the week, such as Monday, Wednesday, and Friday.
[ServiceJob(nameof(MyScheduleJob), "Primary", "00:00:00:05",
JobSchedule.Interval,
DaysOfWeek.All)]
public class MyScheduleJob : IServiceJob
{
public Task<Response<object?>> Execute(JobServiceContext context)
{
// Do something
return Task.FromResult(ServiceResult.Success("Success!"));
}
}

Components

React Components

Use the many provided components to facilitate interaction with your entities. React is not required to use Xams.

useFormBuilder.
The `useFormBuilder` hook allows you to create forms for your entities without requiring binding logic.
DataTable.
Create datatables for your entities with the `DataTable` component. It supports sorting, filtering, pagination, creating records, and a variety of options.
DataGrid.
A simple grid component allows for Excel-like editing.
const MyComponent = () => {
const formBuilder = useFormBuilder({
tableName: 'Widget',
});
return (
<div className="h-full w-full p-6">
<FormContainer formBuilder={formBuilder}>
<div className="flex flex-col gap-4">
<Grid>
<Grid.Col span={6}>
<Field name="Name" />
</Grid.Col>
<Grid.Col span={6}>
<Field name="Price" />
</Grid.Col>
</Grid>
<SaveButton />
</div>
</FormContainer>
</div>
)
}