Jak myślicie: czy tytuł mojego artykułu miał być typowym clickbaitem, służącym przyciągnięciu Waszej uwagi? I tak, i nie. Jeśli tak, to spełnił swoją rolę 🙂 Co ważniejsze, chwytliwy tytuł w pełni oddaje to, o czym zaraz przeczytacie – czym są zewnętrzne obiekty i jak możecie je sami tworzyć. Do dzieła!

External Object – co to takiego?

Dlaczego wziąłem “na warsztat” ten temat? W projekcie, który rozwijam jako developer Salesforce, praca z External Objects to jedno z moich codziennych zadań. Zadanie ciekawe, ale zdążyłem przekonać się na własnej skórze (albo na własnym kodzie :)), że chwilami niełatwe i może przysporzyć trudności. Mam już na nie kilka swoich sposobów – wierzę, że przydadzą się i Wam.

Ale na początek – co to jest External Object? Tworzymy go, gdy chcemy korzystać w aplikacji zbudowanej w Salesforce z danych, które pochodzą spoza Salesforce. Najczęściej External Object to tabela i na pierwszy rzut oka przypomina typowy (standardowy) obiekt Salesforce. Ale ma tylko jedno wspólne standardowe pole – Id. Pozostałe standardowe pola są inne (brak takich pól, jak Created Date i Owner, występują pola External Id i Display URL).

 

Dlaczego warto używać External Objects?

Moim zdaniem, powody są trzy. Wszystkie łączy jedno: oszczędność miejsca i czasu.

  1. Storage (miejsce) – zyskujemy miejsce, bo nie ma konieczności przechowywania wszystkich danych w Salesforce.
  2. Archiwalne/zewnętrzne dane – mamy do nich szybki i łatwy dostęp.
  3. Przetwarzanie poza Salesforce – odciążenie i tak już przepracowanego orga.

 

External Objects – duże możliwości, drobne ograniczenia

Korzyści z używania External Objects jest znacznie więcej niż drobnych niedogodności. Najważniejsze to wiedzieć, że ograniczenia są i podczas pracy “mieć je z tyłu głowy”. Te główne dotyczą:

  1. Raportów.
    Są dostępne, o ile na adapterze Odata nie włączymy opcji High Data Volume.
  2. Security (bezpieczeństwa).
    Brak Sharing Rules i możliwości ich tworzenia (ale przy adapterach Cross Org obowiązują nas te, które stworzone są na orgu źródłowym). Można wprowadzić autentykację per user: wówczas ustalamy, że każdy użytkownik loguje się swoim kontem do bazy danych.
    Object/Field Level Security są dostępne standardowo – można je definiować na profilach i permission setach i działa to tak, jak w przypadku standardowych obiektów.
  3. Limitów.
    Query – wyszukiwanie nowych rekordów – gdy szukamy ich w zewnętrznych źródłach danych, Salesforce przypisuje im swoje Id. Limit to 100 tys. na godzinę, dzielony między wszystkie źródła, dodanie nowych źródeł nie zwiększa limitu.
    OData – callout – limit to 1K dla Developer Edition, 20K dla pozostałych. Jest to soft limit, możliwy do powiększenia.
    Synchronizacja – 200 obiektów per org.
    Triggery – brak w Salesfroce, ale można stworzyć w zewnętrznej bazie danych.
    Formuły – brak możliwości utworzenia.

Warto pamiętać, że External Objects nie wspierają niektórych funkcji i w tych sytuacjach czeka nas trochę “ręcznej” pracy. Przykłady takich funkcji to:

INCLUDES
LIKE
EXCLUDES
toLabel()
AVG
COUNT()
HAVING
GROUP BY
MAX()
MIN()
SUM().

 

Konfiguracja External Objects – kilka przydatnych opcji

Zacznijmy od Custom Query Option (OData 2.0)/Free-Text Search Expressions (OData 4.0). Pozwalają one na zastąpienie wyrażenia “filter” w zapytaniu do zewnętrznego źródła (dowolne wyrażenie dla Custom Query Option i “search” dla Free-Text Search Expressions). Salesforce rekomenduje włączenie tych opcji. Co nam to daje? Wyobraźmy sobie, że mamy już nasz External Object i korzystamy z globalnej wyszukiwarki. Obiekt ma 30 pól tekstowych (w tym 10 long text area). Jak wygląda cały proces przeszukiwania? Salesforce robi to po wszystkich polach tekstowych, więc takie zapytanie będzie bardzo obciążające dla bazy danych. Gdy wybierzemy jedną z powyższych opcji, możemy sami zdecydować, jakie pola przeszukujemy.

Kolejna opcja to High Data Volume. Jak działa? “Zdejmuje” z Salesforce określone limity. Jeśli ją włączymy, “zniknie” na przykład wspomniane ograniczenie w wyszukiwaniu rekordów do 100 tys. – Salesforce przestanie nadawać Id nowym rekordom. Ale uwaga: opcja nie współpracuje z ustawieniem Writable External Objects. Czyli – nie możemy jej włączyć, jeśli zamierzamy edytować externalowe rekordy. Dodatkowo, rekordy te nie będą dostępne w Lightning, będą dostępne tylko w wersji Classic.

Przyda się też opcja pod nazwą External Change Data Capture. Jest ona dostępna dla Odata 4.0. Jak już wiecie, niedostępne są triggery. Ale gdy skorzystamy z tej opcji, a w bazie nastąpi modyfikacja rekordów, w Salesforce będzie to widoczne jako event, informujący o zmianie w konkretnym obiekcie. Może to być event dobrze Wam znany, bo typowy dla Salesforce – Change Event: znajdą się w nim informacje o tym, jaki obiekt został zmodyfikowany, usunięty czy stworzony, jakie pola się zmieniły itp. Ważne, aby pamiętać, że informacje dotyczą tylko tych pól, które nie są puste (chyba że zawartość została usunięta w trakcie aktualizacji). Ponadto, adaptery OData nie rozróżniają “create” i “update”, dlatego event pojawi się zawsze w type update, niezależnie od rodzaju aktualizacji.

I wreszcie opcja pod nazwą Server Driven Pagination. Salesforce rekomenduje, aby jej używać i opierać się na paginacji z zewnętrznego źródła danych. Dlaczego? Gdy przetwarzamy duże zbiory i w tym czasie coś jest dodawane do tabeli lub z niej usuwane, może się zdarzyć, że niektóre rekordy zostaną pominięte albo przetworzone dwukrotnie.

 

Konfiguracja External Objects – na co zwrócić uwagę?

Oto moje “tipy” – wybrałem dla Was kilka najważniejszych. Pierwszy dotyczy Id: gdy tworzymy nowy obiekt, otrzymuje on Id, które nadaje mu Salesforce. Mamy też External Id, niezależne od tego, jak nazywa się kolumna. Salesforce zapowiedział, że w przyszłości Id nadawane obiektom będą tymczasowe. Nie należy zatem opierać logiki na Id od Salesforce, ale na External Id, czyli pochodzących z zewnętrznej bazy danych.

Kolejny tip dotyczy ponownej synchronizacji obiektów. Warto zwrócić uwagę, że nadpiszą się wówczas typy danych. Dla przykładu: w zewnętrznej tabeli mamy dane typu String/Text, gdzie trzymamy Id obiektu w Salesforce. Synchronizujemy taki obiekt, dostajemy pole typu Text i  mapujemy je na Lookup. Załóżmy, że po drodze w tabeli coś się zmieniło, doszły nowe pola, więc robimy ponowną synchronizację. Salesforce, jak wcześniej, nadpisuje to jako Text, przez co zrywa relacje. Dlatego najlepiej utworzyć pola ręcznie lub dodać na środowisku testowym i wrzucić na produkcję np. change setem.

Podobnie jest w przypadku funkcji Enable Search. Możemy zdefiniować wyszukiwanie na źródle danych oraz tę samą opcję na poszczególnych obiektach: w ten sposób zdecydujemy, które obiekty mają być wyszukiwane w Salesforce. Następnie, jeżeli “odznaczymy” tę opcję na wybranym obiekcie, po czym ponownie go zsynchronizujemy, wartość jest nadpisywana wartością ze źródła danych. To ważne – aby nie “zapchać” bazy danych niepotrzebnymi requestami.

I wreszcie – indeksy. W Salesforce ich nie definiujemy, obowiązują nas zatem te, które są zdefiniowane po stronie zewnętrznego źródła danych. Czy warto je zakładać? Tak – jeśli zależy nam na szybszym wyszukiwaniu.

To, o czym właśnie przeczytaliście, było tematem mojej prezentacji 27 stycznia 2022 roku na SForce – Poland Salesforce Meetup. Może macie ochotę obejrzeć moją prezentację?

Obejrzyj webinar
Autor
  • Łukasz Starus
  • Salesforce Developer
  • Salesforce developer po Akademii Craftware. Z wykształcenia absolwent Politechniki Łódzkiej. Wybrał pracę w Salesforce, bo, jak sam mówi, wciąż ma za dużo włosów na głowie 🙂 Wcześniej był trenerem personalnym, a jego ogromnym hobby jest downhill (ekstremalna odmiana kolarstwa górskiego), gdzie startuje w zawodach. Gdy akurat nie pracuje, najłatwiej spotkać go w lesie, gdzie spędza czas, obijając się o drzewa i szykując do kolejnych wyścigów.

Opracowanie redakcyjne:
Ania Sawicka
Redakcja tekstu
Podobał Ci się mój artykuł?
Jeśli nie widzisz formularza, spróbuj wyłączyć adblocka.

Jeśli tak, zapraszam Cię do grona najlepiej poinformowanych czytelników bloga. Dołącz do naszego newslettera, a nie ominą Cię żadne nowości.