Паям Мусави

11 ноември 2018 г. · 9 минути четене

След няколко години работа с Ruby On Rails - аз съм голям фен! - Мислех, че е време да науча друга уеб рамка и след проучване избрах Elixir и Phoenix по много причини като производителност, латентност и разбира се Erlang VM. Смятам, че разработчиците на Ruby ще намерят тази мощна рамка за невероятна и лесна за научаване, тъй като синтаксисът е наистина близък до това, което предлага.

интерфейс

В този урок ще се заемем да създадем REST API бекенд, използвайки Phoenix. Също така ще използваме някои страхотни пакети, за да удостоверяваме потребителите и да ги упълномощаваме за достъп до нашите API.

Трябва да инсталирате Elixir и Phoenix. Използвам Elixir 1.7.3 и Phoenix v1.3.4. Можете да проверите версиите, като стартирате:

Нека създадем първото си приложение на Phoenix JSON API, като изпълним тази команда:

Току-що създадохме приложението без HTML изобразяване и изграждане на активи, тъй като не е необходимо да изобразяваме статично съдържание.

Сега отворете config/dev.exs и ще видите, че приложението работи на порт 4000. Адаптерът на базата данни по подразбиране при създаването на приложение Phoenix е Postgres. Актуализирайте вашите идентификационни данни за PostgreSQL:

Обратно към вашия терминал, изпълнете следните команди, за да създадете базата данни на приложенията и да стартирате сървъра:

Ако видите грешка относно plug_cowboy, добавете пакета към mix.exs:

Стартирайте микс deps.get за да инсталирате пакета и след това да стартирате сървъра отново, като използвате mix phx.server и посетете http: // localhost: 4000. Ще видите грешка:

Това е така, защото все още не сме определили никакъв маршрут! Нека засега определим прост индексен маршрут. Актуализирайте router.ex като този:

Добавихме конвейер: браузър за да се позволи обработка на HTML заявки. Можете да прочетете повече за тръбопроводите тук. Сега нека създадем нашия lib/busi_api_web/controller/default_controller.ex:

Сега презаредете страницата и няма да видите грешка, а само обикновен текст.

Elixir mix се предлага с много полезни генератори и има някои специфични за Phoenix за създаване на ресурси. Във вашия терминал изпълнете следната команда и проверете вградените генератори:

Да предположим, че искаме да имаме списък с активни бизнеси. За да създадем нашите JSON API с нашия модел, трябва да използваме mix phx.gen.json . Ето ни:

Може да попитате „Какво е директория?“. Phoenix 1.3 имаше някои промени в сравнение с по-старите версии. Една такава промяна е, че тя ни позволява да разделяме логиката на домейна в различни модули, наречени контекст. И така, решихме да имаме цялата логика относно нашия бизнес модел (и вероятно други ресурси) в Директорията context, която е отделна папка в проекта.

Командата микс току-що създаде набор от файлове, включително контролер и файл за миграция и някои тестови файлове. Тогава Phoenix ни моли да добавим този ресурс към нашия lib/busi_api_web/router.ex и актуализирайте базата данни с микс ecto.migrate:

Нека да стартираме mix phx.routes за да видите нашите маршрути:

Преди да тестваме нашите приложни програмни интерфейси (API), нека добавим някои първоначални данни. Отворете priv/repo/seed.exs и добавете тези редове:

Сега стартирайте mix run priv/repo/seed.exs. Току-що използвахме псевдоним за да създадете 2 псевдонима за Repo и бизнес модули, които да ги използват за създаване на записи. Рестартирайте сървъра си и отворете http: // localhost: 4000/api/business, за да видите записите JSON.

Ако искате да създадете нов запис с помощта на POST API, просто изпълнете тази команда curl във вашия терминал (или използвайте Postman):

Имайте предвид, че предаваме данните в „бизнеса“ поле, тъй като API очаква параметрите да бъдат изпратени в това поле (Проверете business_controller.ex).

Време е да проучите кода! В цялата история ще видите страхотен оператор, наречен pipe (|>), което е наистина полезно в случай на множество извиквания на функции. Може да искате да прочетете и малко за съвпадението на шаблоните преди да продължим.

Нека започнем с BusinessController. Току-що научихме за псевдонима, така че го пропускаме. Имаме 5 действия (API), включително индексиране, показване, създаване, актуализиране и изтриване. Тези действия извикват някои функции от Директорията модул за извличане/манипулиране на обекти с данни. Например list_bususiness () в модула връща всички записи от бизнес таблицата:

Прекарайте известно време в проверка на тези модули, за да разберете по-добре какво се случва в слоя данни на приложението Phoenix.

Друга интересна функция е action_fallback което се нуждае от някакво обяснение. По принцип се използва резервно действие за улесняване на кода, за да можем да се съсредоточим върху състоянието на успех на тези функции на Repo. Ако се случи нещо лошо (като проверка на данни или нарушение на ограничения), операторът action_fallback извиква съответната функция от FallbackController, в противен случай ресурсът ще бъде създаден или актуализиран. The с изразът се грижи само за кортеж, който е начинът, по който работят повечето функции на модула:

Например create_business функция може да върне кортеж като този след състояние на успех:

или състояние на грешка:

Това наричаме Changeset което ще обсъдим повече. Можете да тествате това, като стартирате iex -S mix във вашия терминал и:

Сега нека проверим нашия бизнес модел:

Освен дефинирането на полетата и техните типове данни, има и набор от промени функция и неговата работа е да предава входните параметри в полетата на модела и да ги валидира. Така например, можем да изпълним предишната команда curl, но този път без да подаваме полето „tag“. Ще видите тази грешка:

Последното нещо, което искаме да прегледаме, е изгледът JSON, който предоставя изходните данни чрез API-тата. Отворете изгледи/business_view.ex:

Ако искате да промените изхода или да добавите други полета (като полета с времеви клей: insert_at, updated_at), тук трябва да актуализирате кода. Този модул също има добър начин да изобрази много записи с данни с render_many. Можем да актуализираме функцията за рендиране, за да върне insert_at поле:

Използвахме NaiveDateTime модул за преобразуване на стойност за дата и час в низ. Опреснете http: // localhost: 4000/api/business, за да видите резултата.

Не искам да говоря за TDD тук, защото изисква друга пълна статия. Но нека пуснем нашите тестове, за да проверим дали всичко е наред. Първо създайте тестовата база данни и изпълнете миграциите:

Ще видите, че има 2 грешки, защото добавихме още едно поле към нашия бизнес JSON изход:

Нека ги поправим. Отворете test/busi_api_web/controllers/business_controller_test.exs и актуализирайте това твърдение, което се използва в 2 тестови случая, опишете „създаване на бизнес“ и опишете „актуализиране на бизнеса“:

Сега стартирайте микс тест отново и ще видите, че всички тестове са преминали успешно.

Досега създадохме RESTful бекенд с някои API за нашия ресурс CRUD. Сега искаме да ограничим достъпа до тези API, като разрешим достъп само на регистрирани потребители. пазач е пакет Elixir за удостоверяване. Имаме нужда и от Комонин за шифроване на парола. Нека ги добавим към нашия списък със зависимости в mix.exs. Ще използваме и Bcrypt като нашия алгоритъм за хеширане:

Сега стартирайте mix deps.get за да инсталирате тези пакети. Трябва да създадем друг JSON ресурс за управление на нашите потребители (въпреки че няма да използваме всички действия, по-лесно е да използваме генератори):

Актуализирайте рутера, за да отразява потребителските приложни програмни интерфейси (регистрация и влизане):

След това стартирайте mix ecto: migrate за създаване на потребителска таблица.

Отворете lib/busi_api/accounts/user.ex за да направите някои промени:

Затова добавихме ново поле към потребителската схема - парола - което е виртуално поле. Както може би се досещате, това ново поле няма да се запази в базата данни, но ние го използваме за процеса на валидиране. encrypted_password ще бъдат записани в DB. Също така актуализирахме набора от промени функция за валидиране и проверка на формат. За шифроване на парола, създадохме частна функция - put_hashed_password - за хеширане на паролата с помощта на Comeonin/Bycrypt. Тази функция получава набора от промени (непостоянен потребителски обект) и актуализира encrypted_password ако наборът от промени е валиден.

Нека създадем потребител, за да сме сигурни, че горният код работи! Във вашия терминал стартирайте iex -S mix:

Можете също да тествате API, като използвате curl:

Сега нека импортираме Guardian правилно! Отворете config/config.exs и добавете това в края на файла:

Заменете SECRET с изхода на mix guardian.gen.secret.

След това трябва да добавим модул за удостоверяване, за да използваме Guardian (JWT е типът на маркера по подразбиране). Създайте lib/busi_api_web/auth/guardian.ex:

Този модул ни помага да създаваме маркери, да ги декодираме, да опресняваме маркерите и да ги отменяме. Сега отворете user_controller.ex и добавете псевдоним към този модул:

И актуализирайте действието за създаване и премахнете останалите действия, тъй като тук нямаме нужда от тях (индекс, показване, актуализиране, изтриване):

Добавихме функция Guardian, за да създадем JWT токен след създаването на потребител. Също така правим „user.json“ за изпращане на JWT токена като част от отговора. Но трябва да актуализираме изгледа. Отворете lib/busi_api_web/views/user_view.ex и го актуализирайте:

Сега извикайте API:

което отговаря с:

Нека създадем друг API за потребителите да влизат. Първо, трябва да създадем нова функция в lib/busi_api/accounts/accounts.ex за връщане на потребител въз основа на имейл:

Сега се нуждаем от функция за удостоверяване на потребител. Поставяме го в lib/busi_api_web/auth/guardian.ex:

Както забелязахте, добавихме 3 функции, за да получим потребител по имейл, проверете дали паролата съвпада с криптирана парола с помощта на checkpw функция на Comeonin и накрая създайте токена. Вижте как използвахме съвпадение на шаблони, за да получим маркера от Guardian encode_and_sign функция:

Тъй като добавихме още един статус на грешка - неоторизиран - трябва да актуализираме fallback_controller.ex да действа при получаване на това състояние чрез добавяне на друга функция за повикване:

Създайте действие в user_controller.ex:

Сега тествайте API:

След като активирахме удостоверяване в нашето приложение, можем да ограничим достъпа до определени ресурси с помощта на Guardian Pipelines. Нека създадем нашия модул за конвейер в lib/busi_api_web/auth/pipeline.ex:

И модул за обработка на грешки в lib/busi_api_web/auth/error_handler.ex:

Сега трябва да добавим нов конвейер към нашия router.ex:

И актуализирайте обхвата на api:

Затова добавихме auth тръбопровод към API, които трябва да ограничим достъпа. Сега, ако се обадите/api/business, ще получите неудостоверена грешка:

Трябва да изпратите своя JWT токен - който получавате, след като влезете - за да получите резултата:

Имайте предвид, че използваме оторизация на HTTP носител.

Поздравления! Приложението е готово.

Можете да проверите други функции на Guardian, в случай че ви се наложи например достъп до текущия потребител или отмяна на маркер за целите на излизане:

Създадохме RESTful бекенд, използвайки Elixir/Phoenix който излага някои CRUD и API за удостоверяване. За достъп до API, потребителят трябва да се регистрира и да влезе, за да получи JWT токен. Използвахме Guardian и Коменин за целите на удостоверяване и упълномощаване.

Надявам се тази статия да ви е харесала. Можете да изтеглите изходния код от моя Github: pamit/elixir-phoenix-json-api.