шаблон для спільного використання об'єктів між API та додатком


9

У мене є серйозні сумніви щодо дизайну мого веб-додатка.

Я хотів відокремити бізнес-логіку від інтерфейсу, тому я зробив веб-API, який обробляє всі запити до бази даних.

Це веб-API ASP.NET з Entity Framework та одиницею роботи та загальним шаблоном сховищ. Поки все добре.

ПРОБЛЕМА

Якщо мені потрібна допомога, я не можу знайти ефективний спосіб спільного використання об’єктів між API та програмою.

Я не хочу безпосередньо серіалізувати об'єкт сутності, я вважав, що це буде поганою практикою, тому що якщо модель сутності зміниться, я могла б закінчитися серіалізацією великих об'єктів без причини.

Як це зараз реалізовано

Оскільки мій інтерфейс - це веб-додаток ASP.NET в C #, а мій API - у C #, я створив спільну бібліотеку з визначенням усіх моїх класів, якими я хочу поділитися між ними.

Я знаю, що рішення не спрацює, коли я буду розробляти додаток для android, мені доведеться створювати свої класи знову на Java, але це не моя найбільша проблема.

Проблема в тому, що я відчуваю, що я завжди перетворюю свої об'єкти.

ПРИКЛАД

Ось приклад моєї роботи:

Я починаю з моделі з усіма об'єктами та анотаціями даних для моєї форми, тоді користувач розмістить цю модель на контролер.

У контролері я повинен перетворити цю модель у клас своєї загальної бібліотеки, а потім надіслати цей об’єкт моєму API.

Тоді контролер у моєму API записує виклик та перетворює цей об'єкт в об'єкт сутності для оновлення бази даних.

Тож у мене 3 класи

  1. Модель перегляду з усіма примітками даних для перевірки (Клієнт)
  2. Загальні класи бібліотеки для обміну об'єктами (DLL)
  3. Класи сутності (API)

У мене є відчуття, що я роблю щось справді не так. Чи є щось більш елегантне? Я хотів би переконатися, що в мене є гарне рішення цієї проблеми, перш ніж проект стане занадто великим.


Якщо моє запитання не зрозуміло, не соромтеся задавати питання.
Марк

Мені незрозуміло, яку архітектуру ви реалізували (можливо, саме таке .net формулювання мене спантеличує) - це 3-х рівнева архітектура: клієнт, сервер, db?
Енді

Так, у мене є веб-додаток, який використовує веб-API. API - це той, що має логіку бізнесу з базою даних.
Марк

Відповіді:


12

Я знаю, що може здатися, що ти перетворюєш об'єкти назад і назад весь час між об’єктами бази даних, об’єктами передачі даних, клієнтськими об’єктами з логікою перевірки тощо, але я б сказав, що ні, ви нічого не робите неправильно .

Кожен з цих об'єктів може представляти одну і ту ж одиницю інформації, але вони мають дуже різні обов'язки. Об'єктом бази даних є ваш інтерфейс зв'язку з базою даних і повинен зберігатися в рівні бази даних, оскільки він може мати або не мати різних анотацій метаданих бази даних та / або зайвих відомостей про реалізацію бази даних у ній.

Об'єктом передачі даних є інтерфейс зв'язку із вашими споживачами API. Вони повинні бути максимально чистими, щоб полегшити споживання з різних мов / платформ. Це може накласти певні обмеження щодо того, як вони виглядають та поводяться залежно від того, яких споживачів API ви хочете підтримати.

Об'єкти вашого клієнта з логікою перевірки насправді не є частиною вашого проекту API, вони є частиною вашого споживчого проекту. У цьому випадку вони не можуть бути такими ж, як об'єкти передачі даних, оскільки ви додаєте до них додаткову логіку (в цьому випадку атрибути перевірки), про яку сервер нічого не знає (і нічого про це не повинен знати!) вважайте ці об’єкти частиною свого API, оскільки вони насправді це не так. Вони дуже специфічні для споживчих додатків, а деякі програми, які споживають ваш API, можуть навіть не потребувати створення цих об’єктів і можуть так само вижити лише на ваших об'єктах передачі даних. Наприклад, якщо у вас не було необхідності перевірки, вам не знадобиться додатковий шар об'єктів, повністю ідентичний вашим об'єктам передачі даних.

Мені здається, що кожен з трьох типів об'єктів дуже добре відповідає одній відповідальності, яка полягає в чистому кодуванні та належній практиці. На жаль, чистий код та передовий досвід іноді означають, що ви пишете багато зайвого коду та перестрибуєте зайві обручі «просто тому». І під час кодування може бути важко оцінити значення, яке воно вам надає, - але як тільки ви випустите заявку і почнете її підтримувати або додавати нові функції для наступної версії, ви, напевно, почнете оцінювати, що ви витратили час на В першу чергу належним чином розділіть ці проблеми. (Не кажучи вже про те, що ви

Я також ненавиджу написання коду перетворення між різними типами об'єктів, як це, але моє рішення, як правило, є одним із наступних:

  • Використовуйте бібліотеку, яка робить для вас більшу частину перетворення об'єктів, наприклад, якщо ви використовуєте C #, ви можете використовувати фантастичну бібліотеку AutoMapper ( http://automapper.org/ ). Я вважаю, що є кілька інших подібних бібліотек, але AutoMapper - це найпотужніша, яку я бачив досі.
  • Якщо ви не можете знайти бібліотеку, яка допоможе вам перетворити об'єкти, напишіть набір корисних методів для перетворення між ними. Це може бути смоктанням, але це варто того, що, зрештою, потрібно записати метод перетворення, коли вам потрібно щось перетворити - не чекайте.

Дякую за ваші пояснення, але мені все одно важко щось зрозуміти. Я не розумію, чому шар для передачі даних не має жодної перевірки? Що робити, якщо я забуду деякі перевірки для свого наступного мобільного додатка? Принаймні, це не підтверджує, коли я викликаю API, а не робити виняток у своїй моделі бази даних. Я не впевнений, що розумію.
Марк

1
Я не кажу, що не слід перевіряти на рівні API. Якщо чесно, це єдине найважливіше місце для перевірки. Перевірка вашої програми - це лише «приємна функція», яка допомагає вашим користувачам не помилятися, перевірка ваших об’єктів передачі даних - це запобігання зловмисним та помилковим даним. Оскільки це різні випадки використання, можливо, вам знадобиться використовувати різні рамки перевірки (ви будете використовувати різні рамки перевірки, якщо ваша програма та ваш api не написані однією мовою), і ви можете перевірити трохи різні речі на кожному рівні (Прод. у наступному коментарі)
wasatz

1
Тож слід перевірити об'єкти передачі даних. Але ви також повинні переконатися, що спосіб їх перевірки не вводить випадково залежностей від будь-яких інших рамок . І звичайно, як я вже говорив раніше, ви насправді не можете бути впевнені, що ваші об’єкти передачі даних взагалі були перевірені або що вони були перевірені в одній і тій же рамці - тому ви повинні "двічі перевірити".
wasatz

2
Головним чином, ви повинні спробувати розглядати свою програму та API як два абсолютно різні програми. Ви можете їх одночасно розгортати, і вони можуть перебувати в одному і тому ж проекті візуального студійного проекту / затемнення. Але це справді дві абсолютно окремі програми. Працюючи у своїй програмі, спробуйте "забути", що ви є тим, хто створив API, і використовуйте його так, як це було б із звичайним стороннім API. Таким чином у вас буде більше шансів побачити, як почуватимуться інші при використанні вашого API та виправляйте найгірші частини на початку.
wasatz

1
І те ж саме, звичайно, стосується роботи над вашим проектом API, спробуйте уявити, що ви пишете послугу, яку збираються використовувати багато сторонні розробники. Постарайтеся не думати занадто багато про свою поточну програму, а скоріше слідкуйте за тим, "які послуги я надаю" і припускаючи, що всі, хто використовує ваш API (в тому числі і ви), є злі люди, які намагаються вбити ваш сервер і змусити видалити всю вашу базу даних.
wasatz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.