Съдържание

Част I: Настройка и показване на кратки URL адреси с помощта на GraphQL

В тази поредица от публикации ще обясня как да създам прост инструмент за съкращаване на URL адреси с помощта на React, Apollo и GraphQL (Graphcool). GitHub repo проектът се намира тук.

Идеята зад инструмента за съкращаване на URL адреси е проста — инструментът за съкращаване взема дълъг URL като www.example.com/thisisalongurl и го съкращава до http://goo.gl/ABC. При достъп до съкратен URL адрес услугата го разширява до оригиналния URL адрес и ви пренасочва там. Алгоритъмът, който ще използвам за изчисляване на хеша (кратък URL адрес), е обяснен „тук“.

Ето някои от по-големите области и функции, които ще внедрим:

  • Настройка и показване на кратки URL адреси с помощта на GraphQL (тази публикация)
  • Създаване на кратки URL адреси
  • Статистика за кратки URL адреси (брой кликвания и т.н.)
  • Изтичащи URL адреси (напр. без кликвания за X седмици/месеци/години)
  • Удостоверяване на потребителя

Използвани технологии

Ще използваме React и Apollo във фронтенда и Graphcool в задния край.

Предпоставки

Ето предпоставките и инструментите, които ще използвам, за да работя по този проект:

  • create-react-app (Инсталиране с: npm install -g create-react-app)
  • Graphcool CLI (регистрирайте се тук, след което стартирайте npm install -g graphcool, за да инсталирате CLI)
  • VS код

След като имате всичко, можем да започнем с нашия проект!

Създаване на проекта

Ще кръстя този проект Скоро, тъй като не съм много добър в назоваването на нещата. Няма значение как ще го кръстите, просто искам да се уверя, че ако видите това име някъде в урока, знаете за какво имам предвид.

Отворете своя терминал в папката с проекти и започнете, като стартирате create-react-app, за да създадете нов уебсайт на React:

$ create-react-app shortly

Няма да се тревожа много за стила, но в случай че реша да добавя CSS по-късно, вероятно ще използвам библиотеката Tachyons. Можете да добавите маркера за връзка към файла /public/index.html:

<link rel="stylesheet" href="https://unpkg.com/tachyons/css/tachyons.min.css">

За да сте сигурни, че всичко е минало добре, влезте в папката и изпълнете yarn start — ако всичко е наред, трябва да видите уебсайта на React по подразбиране отворен в браузъра ви по подразбиране.

Настройване на GraphQL

Използвам Graphcool CLI, за да настроя и инициализирам проекта GraphQL. Командата за инициализация създава куп файлове, така че нека първо създадем подпапка в основната папка на проекта. Уверете се, че сте изпълнили graphcool login, преди да изпълните командата init.

$ cd shortly
$ mkdir graphcool && cd graphcool
$ graphcool init
Creating a new Graphcool service in .... ✔
Written files:
├─ types.graphql
├─ src
│  ├─ hello.js
│  └─ hello.graphql
├─ graphcool.yml
└─ package.json
...

Graphcool CLI създава следните файлове:

  • graphcool.yml — конфигурационен файл за услугата Graphcool, който препраща към вашите типове, функции без сървър и дефинира разрешения
  • types.graphql— дефинира модела на данни за вашата услуга Graphcool
  • Папка src — съдържа код за вашите функции без сървър

Нека изтрием папката src и премахнем препратките към всеки файл в тази папка от файла graphcool.yml, така че файлът да изглежда така (премахнах и коментарите):

types: ./types.graphql
permissions:
  - operation: "*"

По същия начин премахнете типа User от файла types.graphql и добавете типа Link, който ще използваме за съхраняване на кратките връзки. Ще започнем с много прост модел и ще добавим още към него по-късно.

type Link @model {
    id: ID! @isUnique
    hash: String!
    url: String!
    description: String
}

Дефиницията по-горе е доста ясна — за всяка връзка имаме уникален идентификатор, хеш на низ, URL адрес на низ и незадължително описание. Ако се чудите какъв е удивителният знак в тези полета, това прави това поле задължително. Можете да прочетете повече за данните за моделиране в Graphcool тук.

И накрая, трябва да създадем действителната услуга и да прокараме промените, които направихме, като изпълним командата за разгръщане. Ще изпълнявате една и съща команда всеки път, когато правите промяна във вашите типове или функции:

$ graphcool deploy

Ако създавате нов проект, ще получите подкана да изберете клъстер, където искате да внедрите услугата, име на цел (prod) и име на вашата услуга (Shortly).

Няколко секунди по-късно CLI ще ви даде общ преглед на това, което е добавено/внедрено, както и крайните точки на GraphQL. Ще използваме крайната точка на Simple API в нашия уебсайт React, за да се свържем с GraphQL.

Настройване на Apollo

В този раздел ще инсталираме пакети Apollo към уебсайта на React и ще го използваме за свързване с крайната точка на GraphQL. Първо, трябва да инсталираме пакетите на Apollo, които ще използваме:

$ yarn add apollo-client-preset react-apollo graphql-tag graphql

След като това бъде инсталирано, можем да конфигурираме клиента Apollo да се свързва с нашата крайна точка на GraphQL и да използваме „компонент от по-висок порядък“, за да обвием компонента App с ApolloProvider.

  1. Добавете инструкции за импортиране към index.js:
import { ApolloProvider } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory'

2. Създайте екземпляра ApolloClient — заменете стойността [SERVICE_ID] с тази, която сте получили, когато разположихте услугата Graphcool, или просто изпълнете graphcool info, за да покажете тази информация отново.

const client = new ApolloClient({
    link: new HttpLink('https://api.graph.cool/simple/v1/[SERVICE_ID]'),
    cache: new InMemoryCache(),
});

3. Създайте компонент от по-висок ред, за да обвиете компонента App:

const withApolloProvider = Comp => (
  <ApolloProvider client={client}>{Comp}</ApolloProvider>
);
ReactDOM.render(
    withApolloProvider(<App />),
    document.getElementById('root'));

Компонентът от по-висок ред withApolloProvider е функция, която взема компонент, обвива го в ApolloProvider и връща нов компонент.

Изграждане на React компоненти

Нека добавим библиотеката с типове проп, така че да получим проверка на типовете по време на изпълнение към реквизитите на React. Това е чудесен начин да се уверите, че предавате правилни подпори на вашите компоненти.

$ yarn add prop-types

Ще започнем с Link и LinkList компоненти за показване на твърдо кодиран (засега) масив от връзки.

  1. Създайте папка src/components и файл Link.js. Този файл ще представлява една връзка.

Предаваме единичен елемент за връзка към компонента и го показваме в div.

2. Създайте LinkList.js — този компонент ще се използва за показване на списък с връзки (на тази стъпка използваме твърдо кодиран масив от връзки и след като преминем към GraphQL, ще го премахнем)

3. И накрая, нека актуализираме App.js и изобразим създадения от нас компонент LinkList:

Отворете браузъра, навигирайте до http://localhost:3000 и потвърдете, че можете да видите твърдо кодираните връзки.

Четене на връзки от GraphQL

За да получим данните от GraphQL, трябва да напишем GraphQL заявка, за да извлечем всички връзки. Това е заявката, която ще използваме:

const ALL_LINKS_QUERY = gql`
    query AllLinksQuery {
        allLinks {
            id
            url
            description
            hash
        }
    }`;

gql е помощна функция от react-apollo и я използваме, за да дефинираме заявката на GraphQL. Заявката allLinks беше автоматично генерирана от Graphcool и можем да я използваме за извличане на множество възли. Името на заявката (AllLinksQuery) е нашето име за заявката, а стойностите вътре в allLinks са полетата, които искаме GraphQL да върне.

Друга заявка, която се генерира автоматично за нашия тип, е aLink query. С него можем да направим заявка за единичен възел по id.

Например:

query SingleLink {
    Link (id: "someid") {
        url
        description
    }
}

Можете да прочетете повече за Query API тук.

Сега, след като имаме нашия ALL_LINKS_QUERY, можем да използваме контейнера graphql, за да обвием компонента LinkList. Когато заявката завърши изпълнението, резултатите ще бъдат в обекта props на компонента. Ето актуализирания код в LinkList.js:

Нека обясним какво се случва с горния код, започвайки отгоре.

Редове 4–16
Импортирахме gql и graphql и дефинирахме ALL_LINKS_QUERY.

Редове 20–31
Използваме свойствата за зареждане и грешка в подложката за име на заявката, за да проверим дали данните са извлечени или е имало грешка при извличането на данните. В тези случаи ние или връщаме просто div с текст „Зареждане“ или „Грешка“ (това вероятно трябва да са компоненти, така че можете да ги използвате повторно в сайта си). Ако заявката приключи със зареждането и няма грешки, ние получаваме данните (allLinks) и като последна проверка връщаме div, което гласи „Няма връзки…“, ако няма върнати връзки.

Ред 41
Използвайки graphql контейнер, ние комбинираме компонента и заявката. Също така указваме името за заявката (allLinksQuery), което в крайна сметка е името на проп, което Apollo добавя към нашия компонент.

В този момент можете да отидете до http://localhost:3000, за да получите съобщението Няма връзки. Нека използваме игралната площадка на Graphcool, за да добавим няколко връзки. От командния ред стартирайте graphcool playground, за да отворите детската площадка. Като алтернатива можете да отидете на http://graph.cool и да отворите потребителския интерфейс на детската площадка от там.

За да създадем нова връзка, ще напишем GraphQL мутация. Копирайте мутацията по-долу в игралната площадка на Graphcool:

mutation CreateLinkMutation {
  createLink(
    description:"First link from GraphQL",
    url:"http://example.com",
    hash:"somehash") {
    id
  }
}

Както при заявките, Graphcool създава мутация createLink за нас — предоставяме стойностите за задължителните полета и връщаме идентификатор на създадената връзка. Щракнете върху бутона за възпроизвеждане на игралната площадка, за да изпълните заявката и резултатът от мутацията трябва да бъде подобен на този:

{
  "data": {
    "createLink": {
      "id": "cjbr3vlnqhg1a0152fx0qpdel"
}

Забележете как съдържа стойността на полето id — бихме могли също да върнем всяка друга стойност на полето, като просто добавим име на поле към мутацията.

Сега, ако се върнете в приложението React и опресните, първо трябва да видите съобщението за зареждане и накрая, след като заявката се зареди, ще видите връзката, която сте създали.

Това е краят на част I. В предстоящата публикация ще добавя компонент на React за създаване на нови връзки, използвайки мутации на GraphQL, ще внедря прост хеш алгоритъм като функция без сървър на Graphcool.

Благодаря за четенето!

Можете да ме последвате в Twitter и GitHub. Ако това ви е харесало и искате да получите известие, когато други части са готови, трябва да се абонирате за моя бюлетин!