Новая (?) Попытка структурировать базовые URL RESTful - PullRequest
0 голосов
/ 19 августа 2011

Мы все любим REST, особенно когда речь идет о разработке API. Делая это в последние годы, я всегда сталкиваюсь с одной и той же проблемой: вложенными ресурсами. Кажется, мы живем по двум краям шкалы. Позвольте мне привести пример.

/galaxies/8/solarsystems/5/planets/1/continents/4/countries.json

Neato. Подобные случаи, кажется, случаются повсюду, независимо от того, в какой форме они материализуются. Теперь я хотел бы иметь возможность выбирать все страны в солнечной системе, в то же время имея возможность выбирать страны с высокой степенью охвата, как показано выше.

Кажется, у меня есть два варианта здесь. Во-первых, я сглаживаю свою вложенную структуру и ввожу множество параметров GET (которые должны быть хорошо документированы и поняты моим пользователем API), например так:

/countries.json?galaxy=8&solarsystem=5&planet=1&continent=4

Я мог бы сгладить все свои ресурсы и выиграть уникальный базовый URL-адрес для каждой конечной точки. Хороший момент ... уникальные конечные точки на ресурс!

Но какова цена? То, что не кажется естественным, не обнаруживается и не ведет себя как древовидная структура под моими ресурсами. Вывод: плохая идея, но хорошо отработанная.

С другой стороны, я мог бы попытаться избавиться от как можно большего количества дополнительных параметров GET, создавая конечные точки, подобные этому:

/galaxies/8/solarsystems/5/countries.json

Но мне также нужно было:

/galaxies/8/solarsystems/5/planets/1/continents/4/countries.json

Кажется, это другая сторона шкалы. Наименьшее количество дополнительных параметров GET, более естественное поведение, но все же не то, что я ожидал как пользователь API.

Большинство API, с которыми я работал в прошлом году, следуют той или иной парадигме. Кажется, есть хотя бы одна пуля, чтобы кусать. Так почему бы не сделать следующее:

Если есть ресурсы, которые вложены естественным образом, давайте вложим их точно так, как мы ожидаем, что они будут вложенными. То, что мы достигаем, - это, во-первых, уникальная конечная точка для каждого ресурса, когда мы остаемся такими:

/galaxies.json
/galaxies/8/solarsystems.json
/galaxies/8/solarsystems/5/planets.json
/galaxies/8/solarsystems/5/planets/1/continents.json
/galaxies/8/solarsystems/5/planets/1/continents/4/countries.json

Хорошо, но как решить начальную проблему, я хотел собрать все страны в солнечной системе, при этом имея возможность выбирать страны, полностью ограниченные галактиками, солнечными системами, планетами и континентами? Вот что для меня естественно:

/galaxies/8/solarsystems/5/planets/0/continents/0/countries.json # give me all countries in the solarsystem 5
/galaxies/8/solarsystems/0/planets/0/continents/0/countries.json # give me all countries in the galaxy 8

… и так далее, и так далее. Теперь вы можете возразить: «Хорошо, но ноль есть…», и вы правы. Выглядит не очень красиво. Так почему бы не изменить два верхних вызова на что-то подобное:

/galaxies/8/solarsystems/5/planets/all/continents/all/countries.json # give me all countries in the solarsystem 5
/galaxies/8/solarsystems/all/planets/all/continents/all/countries.json # give me all countries in the galaxy 8

Аккуратно, а? Так чего же мы достигаем? Никаких дополнительных параметров GET и все еще стабильных базовых URL для каждой конечной точки ресурсов. Сколько стоит? Да, по крайней мере, длинные URL-адреса, особенно во время ручного тестирования с использованием таких инструментов, как curl.

Интересно, может ли это улучшить не только удобство обслуживания, но и простоту использования API. Если так, то почему никто так не подходит? Я не могу себе представить, чтобы быть первым с такой идеей. Таким образом, должны существовать встречные аргументы против такого подхода. Я не вижу никого. Вы?

Мне бы очень хотелось услышать ваше мнение и аргументы за или против такого подхода. Может быть, есть идеи по улучшению ... было бы здорово услышать от вас. На мой взгляд, это может привести к гораздо лучше структурированным API, так что, надеюсь, кто-то прочтет это и ответит.

С уважением. Jan

Ответы [ 2 ]

1 голос
/ 19 августа 2011

Все будет зависеть от того, как представлены данные.Нужно ли пользователю знать галактику #, чтобы найти конкретную страну?Если это так, то, что вы предлагаете, имеет смысл.Однако мне кажется, что то, что вы предлагаете, несмотря на то, что оно хорошо структурировано и представлено, не позволяет клиентам искать дочерний элемент, если родитель не является известным количеством.

В вашем примере, если быконкретный идентификатор для континента. Мне нужно знать планету, солнечную систему и галактику.Чтобы найти конкретный континент, мне нужно было бы получить все для каждого возможного родителя, пока я не найду континент.

Представление структурированных данных таким образом, если это хорошоИспользование этой структуры, когда у вас есть только часть данных, может быть немного громоздким.Все зависит от того, чего вы пытаетесь достичь.

0 голосов
/ 19 августа 2011

URL-адреса вложенных ресурсов обычно плохие.Подход, который я обычно использую, заключается в использовании уникальных идентификаторов.

Создайте свою БД так, чтобы у нее был только один континент с ID 4. Тогда, вместо ужасного /galaxies/8/solarsystems/5/planets/1/continents/4/countries.json, все, что вам нужно, это простой /continents/4/countries.json.Ясный, достаточный и запоминающийся.

Опция маршрутизации :shallow в Rails делает это автоматически.

Для «всех стран в солнечной системе» я бы использовал /solar_systems/5/countries.json, то есть не пытайтесь включить это в общую схему URL.(И обратите внимание на подчеркивание.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...