Mettere tutto insieme - DDD, CQRS, API Web

1

Ho bisogno di una guida esperta. Sto cercando di apprendere i concetti e di implementarli, ed è possibile che io possa essere un po 'troppo ingegnoso. Ma va bene, perché voglio imparare e acquisire esperienza più che mantenerlo semplice. Mi piacerebbe applicare i concetti di DDD e CQRS nel mio progetto ma ho difficoltà a capire come mettere tutto insieme. Devo progettare e implementare il contesto limitato ItemManagement, che fa parte di un sistema più grande.

Innanzitutto, ci sarà un'applicazione web MVC che gli utenti possono utilizzare per gestire l'inventario degli articoli. Alcuni casi di utilizzo di base sono creazione, modifica, check-in / check-out.

Successivamente, voglio un'API Web esterna che questo sito utilizzerà per interrogare i dati e rispondere ai comandi (e anche essere disponibile per altri contesti limitati).

Mettere insieme queste due cose è dove ho bisogno di una guida, specialmente con il comando. Il modo in cui ho immaginato è che posso inviare oggetti comando al rispettivo URL dell'API, ad esempio api / v1 / items / create, api / v1 / items / {id} / edit, api / v1 / items / {id} / checkin, api / v1 / items / {id} / checkout. Ma poi rimango bloccato. Dopo aver ricevuto un comando nell'API, quali passi vengono seguiti per applicare il comando a un'entità di dominio, convalidare le eventuali regole aziendali e in definitiva mantenere le modifiche? Ecco come lo stavo immaginando

    public class Item
{
    public int Id { get; private set; }
    public string ItemName { get; private set; }
    public bool Available { get; private set; }

    public Item(int id, string itemName, bool available)
    {
        Id = id;
        itemName = ItemName;
        Available = available;
    }

    public Item(CreateItemCommand command)
    {
        Id = command.Id;
        ItemName = command.ItemName;
        Available = command.Available;
    }

    public void Edit(EditItemCommand command)
    {
        ItemName = command.ItemName;
        Available = command.Available;
    }

    public void CheckIn()
    {
        Available = true;
    }

    public void CheckOut()
    {
        Available = false;
    }
}

public class CreateItemCommand
{
    public int Id { get; private set; }
    public string ItemName { get; private set; }
    public bool Available { get; private set; }
}

public class EditItemCommand
{
    public int Id { get; private set; }
    public string ItemName { get; private set; }
    public bool Available { get; private set; }
}

Quindi, nelle mie azioni API, gestivo questi comandi come tali:

Crea

        Item item = new Item(createCommand);
        _repository.Add(item);

Modifica

            Item item = _repository.Get(id);
        item.Edit(editCommand);
        _repository.Save(item);

Checkout

            Item item = _repository.Get(id);
        item.CheckOut();
        _repository.Save(item);

Non c'è nessuno in questo esempio, ma qualsiasi violazione invariante di dominio comporterebbe un'eccezione generata dal modello di dominio e in definitiva tornando al client sotto forma di errore 500.

Sono sulla strada giusta qui o sono fuori dalla giusta forma / pratica? Grazie mille per il tuo tempo.

    
posta user1560457 08.09.2018 - 23:59
fonte

2 risposte

1

I am on the right path here or is this way off from proper form/practice?

Sei sulla strada giusta.

The way I have it imagined is that I can send command objects

Questa ortografia non è corretta: non stai inviando comandi oggetti , stai inviando comandi messaggi . Vedi ai confini, le applicazioni non sono orientate agli oggetti .

Dovrai stare attento con il vocabolario qui; i messaggi di comando non sono la stessa cosa del schema di comando descritto nei Gang of Four prenota, e nessuno di questi è esattamente uguale a quello di Grady Booch Command Separazione query .

Il riferimento che desideri è Enterprise Integration Patterns , dove Hohpe descrive la relazione tra i messaggi di comando e comando oggetti.

After receiving a command in the API, what steps are followed to apply the command to a domain entity, validate against any business rules, and ultimately persist the changes?

Normalmente prima convaliderà il messaggio, vale a dire assicurati che il messaggio di per sé sia conforme alle tue specifiche. Quindi si passa quel messaggio al modello di dominio per verificare il messaggio rispetto allo stato corrente e calcolare le modifiche appropriate.

any domain invariant violations would result in exception being thrown from the domain model and ultimately coming back to client in form of 500 error.

Probabilmente non è giusto - se il modello di dominio fa la cosa giusta proteggendo lo stato da un messaggio sbagliato, dovresti usare un codice di stato 4xx.

RFC 5789 include una decente panoramica di come potresti discriminare tra i diversi membri della classe 4xx dei codici di stato.

    
risposta data 09.09.2018 - 15:06
fonte
0

Scusa, sei fuori credo.

Con lo schema di comando si dovrebbe mettere la logica nell'oggetto comando.

Ovviamente questo significa che non puoi inviarli via cavo. Solo i dati possono essere serializzati.

I tuoi oggetti comando, privati della loro logica ora sono solo elenchi di parametri.

    
risposta data 09.09.2018 - 09:04
fonte

Leggi altre domande sui tag