Szybkie prototypowanie backendu z json-serverem

Są sytuacje, gdy piszemy front-end zanim będzie dostępny back-end, lub chcemy postawić lokalną „fałszywą” instancję REST-owego back-endu zwracającą odpowiedzi, nad którymi mamy pełną kontrolę, bez przebijania się przez skomplikowaną logikę przetwarzania prawdziwych danych. Szybką i wygodną opcją jest skorzystanie z pakietu json-server uruchamianego w Node.js i serwowanie danych z pliku.

Nawet jeśli potrzebny back-end jest wygodnie dostępny np. w chmurze AWS, czasem potrzebujemy uzyskać odpowiedź, która dotyczy rzadko pojawiającego się zdarzenia, albo mamy za zadanie zmienić format danych. Kod produkujący odpowiedź może być tak zawiły, że będzie nas nadmiernie spowalniał przy eksperymentowaniu z różnym ukształtowaniem odpowiedzi. Zamiast myśleć o tym, co chcemy uzyskać, będziemy walczyć z problemem, jak to uzyskać. Serwer stawiany przez json-server może znacząco usprawnić naszą pracę, ponieważ w ogóle nie wymaga pisania kodu, naszym zadaniem jest dostarczenie przykładowych odpowiedzi.

Jeśli potrzebujemy „fałszywego” serwera tylko na czas implementacji jednego zadania, możemy umieścić go w /tmp. Gdyby okazał się przydatny w codziennej pracy nad front-endem, proponuję dodać go w podkatalogu repozytorium projektu front-endowego:

% mkdir service-mock
% cd !$
% npm init -y
% npm install json-server

Nie rozumiesz, co dzieje się w drugiej linijce? Wyjaśniam to na końcu artykułu.

Serwer jest prawie gotowy do uruchomienia, potrzebujemy jeszcze zdefiniować, jakie dane ma zwracać. Zakładamy plik db.json:

{
  "users": [
    {"id": "alice", "admin": true},
    {"id": "bob", "admin":  false}
  ],
  "supplies": [
    {"id": 100, "cancelled": false},
    {"id": 101, "cancelled": true}
  ]
}

Mamy tu 2 zasoby REST-owe: users i supplies. Możemy oszczędzić sobie pisania i zapisać uruchamianie serwera do package.json:

  "scripts": {
"server": "./node_modules/.bin/json-server --watch db.json"
},

Uruchamiamy serwer (npm run server) i dostajemy podpowiedź, co możemy robić:

> service-mock@1.0.0 server /tmp/service-mock
> json-server --watch db.json


  \{^_^}/ hi!

  Loading db.json
  Done

  Resources
  http://localhost:3000/users
  http://localhost:3000/supplies

  Home
  http://localhost:3000

  Type s + enter at any time to create a snapshot of the database
  Watching...

Możemy listować każdy z zasobów zdefiniowanych w db.json i pobierać każdy z nich — własność „id” z pliku służy jako identyfikator:

% curl localhost:3000/users
[
  {
    "id": "alice",
    "admin": true
  },
  {
    "id": "bob",
    "admin": false
  }
]
% curl localhost:3000/users/alice
{
  "id": "alice",
  "admin": true
}                                                                                                    

„Fałszywy” serwer reaguje też poprawnie na zapytania modyfikujące dane — możemy np. zrobić PUT i zaktualizować dane:

curl -XPUT localhost:3000/users/bob -H 'Content-Type: application/json' --data '{"id":"bob", "admin": true}'

Można naturalnie uruchomić serwer na porcie innym niż 3000, jest też możliwość kontroli nad generowanymi z JSON-a ścieżkami — wyjaśnia to opis projektu. Pisząc artykuł korzystałem z wersji 0.14.2 pakietu, więc jest szansa, że w momencie, gdy to czytasz, składnia może się różnić.

Bang dollar

Na koniec krótkie wyjaśnienie początkowych kroków tworzenia serwera:

% mkdir service-mock
% cd !$

Co oznacza !$ w drugiej linijce? Jestem zbyt leniwy, żeby pisać w konsoli nazwy katalogów. Mógłbym wpisać „s”, wcisnąć Tab i liczyć na podpowiadanie — ale to działa tylko wtedy, gdy nie ma pliku ani katalogu na literę „s”. Jeśli jest — podpowiadanie zatrzymuje się, muszę zobaczyć, jakie są możliwe opcje, tracę rytm pisania i flow myślowy.

Bezpieczniej jest dla mnie podać ostatni argument ostatniej wpisanej komendy — służy do tego skrót wykrzyknik-dolar, czyli uniksowym slangu „bang-dollar”. Zapytanie o „cd !$” na superuser zwięźle tłumaczy popularne skróty w Bashu. Sam używam Zsh (trochę powodów, czemu Zsh góruje nad Bashem), ale większość skrótów działa tak samo.

Zdjęcie wykonał Colby Gutierrez-Kraybill na licencji CC BY 2.0