Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(http): interceptor API #29

Merged
merged 4 commits into from
Jan 22, 2025
Merged

feat(http): interceptor API #29

merged 4 commits into from
Jan 22, 2025

Conversation

Convly
Copy link
Member

@Convly Convly commented Jan 13, 2025

What does it do?

Major Changes

  • Adds an interceptor API for the HTTP module
    • This API is internal for now and isn't exposed through the public SDK interface. The next step is to think about and release an API to customize HTTP requests easily from the user standpoint (either global or per request interceptors).
    • Adds and removes interceptors (<> middlewares) on request/response's fulfillment or rejection
  • Moves the request and response handling from the HttpClient to the StrapiSDK to remove dependency issues (for example, HttpClient shouldn't know about the AuthManager). Now the core logic is handled by the SDK itself.

Minor Changes

  • Adds http short hands for get, put, post and delete methods for the HTTP module
  • Adds a PathFormatter class to facilitate validation and transformation of common paths (baseURL, requests path, etc...)
  • Updated the unit tests to keep 100% coverage + test complex scenarios (e.g. HTTP client's prototype alteration)

Why is it needed?

Groundwork for next features (user API), clean up imperfections in the architecture, and fix how modules communicate/rely on each other.

How to test it?

  • Run the unit test suites (including with coverage)
  • Using any Strapi app with resources accessible via the content API, create a test file and run it with debug mode enabled (DEBUG=* node index.js) to check if all the requests are done correctly
const { strapiSDK } = require('./dist/bundle.cjs');

const sdk = strapiSDK({
  baseURL: 'http://localhost:1337/api',
  auth: {
    strategy: 'api-token',
    options: { token: '<token>' },
  },
});

const categories = sdk.collection('categories');

categories
  .find({
    fields: ['name', 'locale'],
    filters: { locale: 'en' },
    sort: 'updatedAt:desc',
  })
  .then(({ data, meta }) => {
    console.log('Categories:', data);
    console.log('Pagination', meta.pagination);

    return data.at(0);
  })
  .then(async (latestCat) => {
    const document = await cats.findOne(latestCat.documentId);

    console.log('Found one');
    console.log(document);
  })
  .catch((error) => {
    console.error('Error fetching categories:', error.name, error.message);
  });

You should end up with something similar to this:

  sdk:auth:manager initializing a new auth manager +0ms
  sdk:auth:manager registering default authentication providers +1ms
  sdk:auth:factory registered a new auth strategy: 'api-token' +0ms
  sdk:auth:factory registered a new auth strategy: 'users-permissions' +0ms
  sdk:auth:manager default authentication providers registered successfully +0ms
  sdk:core started the initialization process +0ms
  sdk:core validating the configuration +0ms
  sdk:validators:sdk validating sdk config +0ms
  sdk:validators:sdk validating base url +0ms
  sdk:validators:url validated url successfully: 'http://localhost:1337/api' +0ms
  sdk:validators:sdk validated sdk config successfully +0ms
  sdk:core user config passed the preflight validation +0ms
  sdk:http initializing new client with base url: 'http://localhost:1337/api' +0ms
  sdk:validators:url validated url successfully: 'http://localhost:1337/api' +0ms
  sdk:core init modules +0ms
  sdk:core init http module +0ms
  sdk:core init auth module +0ms
  sdk:core setting up the auth strategy using 'api-token' +0ms
  sdk:auth:manager setting strategy to 'api-token' +0ms
  sdk:auth:provider:api-token validating provider configuration +0ms
  sdk:auth:provider:api-token provider configuration validated successfully +1ms
  sdk:auth:factory successfully instantiated a new 'api-token' provider +1ms
  sdk:core finished the sdk initialization process +1ms
  sdk:ct:collection initialized manager for 'categories' +0ms
  sdk:ct:collection finding documents for 'categories' +0ms
  sdk:utils:url-helper appending query params to '/categories': { fields: [ 'name', 'locale' ], filters: { locale: 'en' }, sort: 'updatedAt:desc' } +0ms
  sdk:utils:url-helper query params appended to url: '/categories?fields%5B0%5D=name&fields%5B1%5D=locale&filters%5Blocale%5D=en&sort=updatedAt%3Adesc' +1ms
  sdk:auth:manager trying to authenticate with api-token +13ms
  sdk:http initializing new client with base url: 'http://localhost:1337/api' +13ms
  sdk:validators:url validated url successfully: 'http://localhost:1337/api' +13ms
  sdk:auth:provider:api-token no authentication step is required for the 'api-token' auth strategy, skipping +12ms
  sdk:auth:manager authentication successful +0ms
  sdk:ct:collection found 2 'categories' documents +46ms
Categories: [
  {
    id: 56,
    documentId: 'ehnp66wbd9oastjn8sk3tdro',
    name: 'Théa',
    locale: 'en'
  },
  {
    id: 38,
    documentId: 'lt50ilsghn37xndnj6ohk9s3',
    name: 'New name',
    locale: 'en'
  }
]
Pagination { page: 1, pageSize: 25, pageCount: 1, total: 2 }
  sdk:ct:collection finding a document for 'categories' with id: 'ehnp66wbd9oastjn8sk3tdro' +1ms
  sdk:ct:collection found the 'categories' document with document id 'ehnp66wbd9oastjn8sk3tdro' +8ms
Found one
{
  data: {
    id: 56,
    name: 'Théa',
    datetime: null,
    date: null,
    createdAt: '2024-12-13T15:36:38.817Z',
    updatedAt: '2024-12-20T15:56:19.837Z',
    publishedAt: '2024-12-20T15:56:19.842Z',
    locale: 'en',
    documentId: 'ehnp66wbd9oastjn8sk3tdro'
  },
  meta: {}
}

Bundle Size Evolution

The bundle grew quite a lot, but this is to be expected in the first few refactor and big features we're gonna introduce at the beginning as we add the main elements powering future capabilities.

Also, not sure why the browser build doesn't grow 🤔

Bundle Before After Change (%)
dist/bundle.browser.min.js 16K 16K +0.00%
dist/bundle.cjs.js 24K 28K +16.67%
dist/bundle.esm.js 24K 28K +16.67%

@Convly Convly added pr: feature New or updates to features source: sdk-http Source is the SDK HTTP client labels Jan 13, 2025
Copy link
Contributor

@innerdvations innerdvations left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't tested it yet, but code LGTM! Nice work!

src/auth/providers/api-token.ts Show resolved Hide resolved
@innerdvations
Copy link
Contributor

innerdvations commented Jan 16, 2025

For some reason this test fails for me locally but passes on the CI:

 ● StrapiSDK › Custom Interceptors › HTTP › fetch should add an application/json Content-Type header to each request

    expect(received).toBe(expected) // Object.is equality

    Expected: "application/json"
    Received: null

      190 |         expect(headers).toBeDefined();
      191 |         expect(headers).toBeInstanceOf(Headers);
    > 192 |         expect((headers as Headers).get('Content-Type')).toBe('application/json');
          |                                                          ^
      193 |       });
      194 |
      195 |       it.each([

      at Object.<anonymous> (tests/unit/sdk.test.ts:192:58)

Update: it fails on Node 20.9.0 but works on 20.12.0, maybe we're relying on a feature that wasn't added until after 20.9?

@Convly
Copy link
Member Author

Convly commented Jan 22, 2025

It seems that a fix has been released after 20.9.0, I've constrained the SDK usage to the latest v20 release as it's in maintenance anyway.

Everything should now be working

@Convly
Copy link
Member Author

Convly commented Jan 22, 2025

Note: I've also updated the version for some of our outdated packages while I was there

@Convly Convly requested a review from innerdvations January 22, 2025 13:30
@Convly Convly merged commit 4037a20 into main Jan 22, 2025
7 checks passed
@Convly Convly deleted the feat/http-api-v2 branch January 22, 2025 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr: feature New or updates to features source: sdk-http Source is the SDK HTTP client
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants