Progettazione del servizio WCF

1

Sono piuttosto nuovo a WCF (o resto, o Json per quella materia) e mi piacerebbe avere alcune opinioni di esperti su quali metodi definire.

Una breve introduzione per dare un'idea di ciò che il webservice dovrebbe esporre: Sto costruendo software domotica (software in grado di controllare una rete ZWave) che ha diverse interfacce (un'applicazione GUI, un server Web per la configurazione e tablet / telefoni per controllare la rete).

Il webservice è l'applicazione centrale che: - ha un controller che può interagire con i dispositivi ZWave - espone un servizio JSON WCF in modo che i client possano interrogare e controllare sulla rete ZWave

I metodi semplici nell'interfaccia WCF:

    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "getnodes")]
    public List<Node> GetNodes()
    {
        // ... retrieve all nodes from ZWave Controller
    }

    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "getnode/{id}")]
    public Node GetNode(uint id)
    {
        // ... retrieve specific node
    }

Quello che mi stavo chiedendo, è come "specifica" l'API dovrebbe essere in termini di metodi POST / PUT. I client devono interagire con i nodi, come impostare il nome, impostare la stanza in cui si trova il nodo, attivare / disattivare un nodo, impostare un importo dim, ecc. Ecc.

Ho definito un metodo come segue:

    [WebInvoke(Method = "PUT", RequestFormat = WebMessageFormat.Json, UriTemplate = "setnodename")]
    public void SetNodeName(NodeNewName nodeNewName)
    {
        // .. sets the name of the node, as specified in the passed object          
    }

Funziona, tuttavia questo causa molti metodi e classi specifiche (come ho specificato un breve elenco sopra la funzionalità che richiederebbe metodi e classi specifici per ognuno di essi).

È questa la strada da percorrere? O dovrei avere un metodo UpdateNode e una classe più generica come parametro che specifica solo le proprietà che devono essere aggiornate? O c'è qualche tipo di linea guida che mi aiuterebbe a definire un solido design per il mio webservice?

Ho cercato molto su questo argomento e ho letto alcuni articoli sulle linee guida per la progettazione di WCF, ma non sono davvero qualcosa su cui coprono questa parte. (o non sono il miglior googler su questo argomento specifico, che avrebbe senso visto che sono nuovo su WCF / REST / Json / etc).

Spero che qualcuno possa capire cosa sto cercando e può aiutarmi nel mio cammino.

Molto apprezzato!

    
posta Haxx 18.10.2015 - 20:44
fonte

2 risposte

2

Questa è una domanda difficile a cui rispondere in modo definitivo, perché questo spazio è ancora relativamente giovane. Quando tutto si calmerà, sapremo quale dovrebbe essere la risposta. :)

Dato che i tipi di oggetti e le loro proprietà specifiche sono potenzialmente illimitate (dipende da cosa viene commercializzato), sarei tentato di considerare ciascun nodo come un bucket di dati. L'estremo estremo di questo sarebbe qualcosa di simile:

public void SetNodeProperty(string name, string value)

public void SetNodeProperties(Dictionary<string, string> properties)

Funziona davvero solo se non hai proprietà nidificate dell'oggetto (invece di node.Temperature.Minimum , dovresti fare node.MinTemperature ) e i tuoi valori di proprietà sono convertibili da stringhe.

Se hai alcuni dati di base come Nome, Stanza, ecc. Puoi basare il tuo oggetto intorno a questo e usare trucchi per comunicare nuovamente le proprietà extra al server. JsonExtensionData è un modo per farlo dove tutte le proprietà extra che non sono proprietà dirette sulla classe vengono messe in una Dictionary<string, object> alla deserializzazione, così puoi accedervi.

public class Node
{
    public string Name {get;set;}
    ...
    [JsonExtensionData]
    public Dictionary<string, object> ExtraData {get;set;}
}

// API
public void UpdateNode(Node node)

Un altro modo sarebbe sfruttare il polimorfismo nella tua API (ecco la versione WCF ) in modo che tutto ciò che implementa INode verrà deserializzato sul tipo concreto corretto sul server (a condizione che il client possa darti un suggerimento sul tipo quando inviano i dati JSON).

// something like this required for WCF polymorphic parameters
[ServiceKnownType("GetKnownTypesOfINode", typeof(MyHelperClass))]
public void UpdateNode(INode node)
// node could deserialize as ThermostatNode, LightSourceNode, etc.
//   but will be cast as INode
// client has to send $type property for JSON.NET to deserialize properly
//   the value for $type usually takes the form:
//   'My.Namespace.SubNamespace.Class, My.Assembly'

In terzo luogo, potresti gestire il JSON in un modo puramente dinamico. JSON.NET ti consente di deserializzare in modo dinamico oppure ExpandoObject per interrogare il corpo JSON pubblicato. Questo supporta le proprietà annidate a differenza del dizionario delle stringhe. Sono abbastanza sicuro che WCF non supporta questo dato che un tema centrale è fornire un'interfaccia come un contratto di dati. Tuttavia, anche nell'API Web, probabilmente leggerò il corpo della richiesta manualmente per evitare di dover creare un raccoglitore modello personalizzato o un filtro o altro.

    
risposta data 19.10.2015 - 22:47
fonte
0

Penso che dovresti seguire il più possibile i metodi specifici.

Definendo nell'interfaccia del servizio ciò che è e non è possibile abiliti il client a disporre di controlli del tempo di compilazione e digitare sicurezza. (supponendo che seguano la definizione dell'interfaccia!)

Se si utilizza una sintassi più fluida, di query / aggiornamento con i propri oggetti o linguaggio generico, è più facile per il cliente commettere errori, ovvero, non so, tentare di "attenuare il rubinetto dell'acqua".

Questo produrrà un errore di runtime, che dovrai trasmettere al client e il client dovrà decodificare e agire. Molto più difficile a tutto tondo.

    
risposta data 20.10.2015 - 00:13
fonte

Leggi altre domande sui tag