How do you substitute HttpClient in Aurelia?

后端 未结 2 2022
独厮守ぢ
独厮守ぢ 2020-12-05 15:29

I\'m brand new to Aurelia.

How would you change the following code to provide a dummy HttpClient, e.g. a json reader instead that would provide just a static set of

相关标签:
2条回答
  • 2020-12-05 15:37

    There is another possibility to provide static data for the application during development. Navigation Skeleton already comes with Gulp and BrowserSync, so we used those to fake API calls.

    Let's say you load JSON data from /api virtual directory, so e.g.

    GET /api/products
    

    In this case your just need two things to fake it.

    Put your mock data into files

    Go to the root folder of your Aurelia app and create an /api folder.

    Create a /api/products subfolder and put a new file called GET.json. This file should contain the JSON, e.g.

    GET.json

    [ { "id": 1, "name": "Keyboard", "price": "60$" },
      { "id": 2, "name": "Mouse", "price": "20$" },
      { "id": 3, "name": "Headphones", "price": "80$" }
    ]
    

    Configure BrowserSync to mock your API calls

    Navigate to /build/tasks folder and edit the serve.js file. Change the definition of serve task to the following code:

    gulp.task('serve', ['build'], function(done) {
      browserSync({
        online: false,
        open: false,
        port: 9000,
        server: {
          baseDir: ['.'],
          middleware: function(req, res, next) {
            res.setHeader('Access-Control-Allow-Origin', '*');
    
            // Mock API calls
            if (req.url.indexOf('/api/') > -1) {
              console.log('[serve] responding ' + req.method + ' ' + req.originalUrl);
    
              var jsonResponseUri = req._parsedUrl.pathname + '/' + req.method + '.json';
    
              // Require file for logging purpose, if not found require will 
              // throw an exception and middleware will cancel the retrieve action
              var jsonResponse = require('../..' + jsonResponseUri);
    
              // Replace the original call with retrieving json file as reply
              req.url = jsonResponseUri;
              req.method = 'GET';
            }
    
            next();
          }
        }
      }, done);
    });
    

    Now, when your run gulp serve, BrowserSync will be handling your API calls and serving them from the static files on disk.

    You can see an example in my github repo and more description in my Mocking API calls in Aurelia.

    0 讨论(0)
  • 2020-12-05 15:55

    There's a couple steps required to get the demo code in your original post to a state where we can substitute HttpClient implementations.

    Step 1

    Remove the configuration code in the class's constructor...

    These lines:

    users.js

    ...
    http.configure(config => {
      config
        .useStandardConfiguration()
        .withBaseUrl('https://api.github.com/');
    });
    ...
    

    Should move to the main.js file:

    main.js

    export function configure(aurelia) {
      aurelia.use
        .standardConfiguration()
        .developmentLogging();
    
      configureContainer(aurelia.container);  // <--------
    
      aurelia.start().then(a => a.setRoot());
    }
    
    function configureContainer(container) {
      let http = new HttpClient();
      http.configure(config => {
        config
          .useStandardConfiguration()
          .withBaseUrl('https://api.github.com/');
      });
      container.registerInstance(HttpClient, http); // <---- this line ensures everyone that `@inject`s a `HttpClient` instance will get the instance we configured above.
    }
    

    Now our users.js file should look like this:

    users.js

    import {inject} from 'aurelia-framework';
    import {HttpClient} from 'aurelia-fetch-client';
    
    @inject(HttpClient)
    export class Users {
      heading = 'Github Users';
      users = [];
    
      constructor(http) {
        this.http = http;
      }
    
      activate() {
        return this.http.fetch('users')
          .then(response => response.json())
          .then(users => this.users = users);
      }
    }
    

    Step 2:

    Mock the HttpClient.

    The user.js module only uses the fetch method which returns a Response object that has a json method. Here's a simple mock:

    let mockUsers = [...todo: create mock user data...];
    
    let httpMock = {
      fetch: url => Promise.resolve({
        json: () => mockUsers
      })
    };
    

    Step 3:

    Reconfigure the container to use the http mock:

    In step 1 we added a configureContainer function to the main.js module that registered a configured HttpClient instance in the container. If we wanted to use our mock version the configureContainer function would change to this:

    main.js

    ...
    
    let mockUsers = [...todo: create mock user data...];
    
    let httpMock = {
      fetch: url => Promise.resolve({
        json: () => mockUsers
      })
    };
    
    function configureContainer(container) {      
      container.registerInstance(HttpClient, httpMock);
    }
    

    More info on configuring the container here: https://github.com/aurelia/dependency-injection/issues/73

    0 讨论(0)
提交回复
热议问题