abnormalize0 / DailyTeleFrog

0 stars 0 forks source link

GET /posts refactor #136

Open serynabatov opened 4 months ago

serynabatov commented 4 months ago

Метод api_pages_get на контроллере.

Разделим все на блоки.

Входной запрос

  1. Тебе не нужен user_id на этом уровне. Во-первых это дубликат информации, если вы хотите использовать oauth 2.0 аутентификацию, то эта информация должна вытягиваться из JWT токена. Не создавай больше сущностей, чем нужно :) (https://stackoverflow.com/questions/56753929/how-to-get-user-id-using-jwt-token)
  2. Если использовать ключ 'sort-column', то необходимо делать это как фильтр. Таким образом это позволит нам сделать масштабируемый фильтр, и таким образом мы туда подключим еще и флаг 'nonsub', и 'sort-direction'. Объединение всех фильтров в один позволит нам не переписывать тысячу раз работу апи (поскольку мы можем переиспользовать фильтр для разных API вызовов на разных страницах сайта)
  3. Ключи upper-date, lower-date, upper-rating и lower-rating содержат в себе границы для соответствующих параметров статей. Ключи include-tags, include-authors и include-communities содержат в себе параметры, все из которых должны присутствовать в статьях в выборке. Ключи exclude-tags, exclude-authors и exclude-communities содержат в себе параметры, ни один из которых не должен присутствовать в статьях в выборке убирай из этого эндпойнта.

Этот подход нарушает основной подход проектирования REST-API. В таких случаях нужно делать разные эндпойнты. Фронт вызовет нужные ему эндпойнты сам, ты должен их предоставить :)

  1. Никогда не передавай данные в хедерах http реквеста. Потому что хедеры http - только для сертфицированного контента, если вы кидаете что-то в хедерах многие провайдеры блокируют такие движения, потому ваш сайт будет открываться только на локальном сервере. Для конкретного этого реквеста в хедере должен быть только Application-type (json), Authorization: Bearer token и все! Остальная информация для этого реквеста должна быть оформлена как Request parameters. Однако помните, если ваш гет запрос содержит много реквест парамов - вы серьезно накосячили с архитектурой, поскольку в таких случаях обычно работает принцип Request Body, который не доступен для гета, а доступен для других запросов, потому рекомендуется при проектировании рест архитектуры, проектировать это таким образом, чтобы в гет запросах было мало параметров. Также такое проектирование блокируется HTTP 2.0, а HTTP 1.1 его разрешают, но "highly discourage it", т.е. на старых браузерах ваш код работать будет онлайн, на новых вам нужно будет просить пользователя устанавливать расширения, позволяющих им читать старые протоколы, так делать не надо. https://developer.mozilla.org/en-US/docs/Glossary/Request_header https://stackoverflow.com/questions/978061/http-get-with-request-body

Response

Я смотрю только на респонс сейчас, пока мы не перешли к самим функциям. Я буду писать комментария по этому поводу

  1. Не делайте json на выход внутри полей. Сейчас preview_content у вас бесформенный и заставляет фронт делать странный иф элс, он должен быть рефакторнут.
  2. Нельзя делать следующее
                        '%COMMENTID%': {
                                            'comment_text': '%STR%'
                                            'author_id': '%INT%'
                                            'likes_count': '%INT%'
                                            'dislikes_count': '%INT%'
                                            'id': '%INT%'
                                            'answers': '%LIST%'
                                    }
                    ]

    COMMENTID должен быть внутри объекта, иначе это создает дополнительную нагрузку на фронт, когда можно это избежать. COMMENTID относится к одной сущности. ДТО должно быть оформлено именно таким образом.

  3. 'tags': '%STR%' - должен быть массивом, не давай джаваскрипту возможность что либо сильно парсить на стороне, когда сервак это может сделать!

Код

  1. Те фиксы, которые я предоставял позволят тебе не использовать parse_structure метод аж 4 раза на уровне контроллера (уровень контроллера в рест апи должен быть в идеале самым тонким, он должен управлять только запросом и его перераспределением если требуется)
  2. parse_structure пока корректироваться не будет, благодаря тому что мы будем правильно использовать Request Param или Request Body в запросе, данные тебе приползут и без плясок с различными типами (вообще оч странное решение, которое создает дополнительную связку с классами)
  3. Я везде вижу что ты для начала почему то статус возвращаешь, а потом сущность, есть какой-то смысл отходить от общепринятого порядка дизайна любого АПИ, где для начала сущность, а потом статус? (см. весь язык ГО например)
  4. В дизайне REST API предполагается, что ошибка просто передается обратно, не нужно возвращать ее каждый раз или выдавать None достаточно сделать throw Exception, где Exception - это кастомное исключение
  5. Очень большое количество вложенностей классов, причем не очень понятно к какому уровню каждая вложенность классов относится. Помни о солиде, и о трех уровнях REST архитектуры, есть контроллер, есть сервисы, есть репозитории. С этим уже тяжело разбираться и искать баги :) https://en.wikipedia.org/wiki/SOLID
  6. Я вижу множество if else на каждом уровне, если ты парсишь огромное кол-во данных - была ошибка при проектировании, мы еще можем исправить это
  7. Все еще рекомендую использовать ОРМ, create_select_request например очень не гибкий, используется один раз, и зависит от огромного количества сущностей. Также ты не используешь prepared statements. По этому поводу хочется вместить старенький мем. image Это совсем быстро овервью, мы можем hop on a call и там поговорить о том каким должен быть дизайн базы данных (которую мы все еще можем поправить) и как должен функционировать REST

Я душный да, но это действительно важно, я тебя очень люблю, Никит, но тут вопрос продукта, а не наших отношений)